当前位置:   article > 正文

Java 基于TCP协议的Socket编程和通信_bufferedwriter out = new bufferedwriter(new output

bufferedwriter out = new bufferedwriter(new outputstreamwriter(socket.getout

  在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。

请求-响应”模式:

      1. Socket类:发送TCP消息。

      2. ServerSocket类:创建服务器。

      套接字是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不同的系统中双向或单向发送,直到其中一个端点关闭连接。套接字与主机地址和端口地址相关联。主机地址就是客户端或服务器程序所在的主机的IP地址。端口地址是指客户端或服务器程序使用的主机的通信端口。

      在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接,这样,客户端和服务器通过套接字所建立的连接使用输入输出流进行通信。

      TCP/IP套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数量的数据。

      实际上,套接字只是计算机上已编号的端口。如果发送方和接收方计算机确定好端口,他们就可以通信了。

TCP/IP通信连接的简单过程:

      位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B计算机的TCP/IP软件接收该消息,并进行检查,查看是否有它知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。

      要使程序有效地运行,就必须有一个客户端和一个服务器。

通过Socket的编程顺序:

      1. 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息)。

      2. ServerSocket调用accept()方法,使之处于阻塞状态。

      3. 创建客户端Socket,并设置服务器的IP及端口。

      4. 客户端发出连接请求,建立连接。

      5. 分别取得服务器和客户端Socket的InputStream和OutputStream。

      6. 利用Socket和ServerSocket进行数据传输。

      7. 关闭流及Socket。

单向通信

服务器端

  1. import java.io.BufferedWriter;
  2. import java.io.IOException;
  3. import java.io.OutputStreamWriter;
  4. import java.net.ServerSocket;
  5. import java.net.Socket;
  6. /**
  7. * 最简单的服务器端代码
  8. * @author Administrator
  9. */
  10. public class BasicSocketServer {
  11. public static void main(String[] args) {
  12. Socket socket = null;
  13. BufferedWriter bw = null;
  14. try {
  15. // 建立服务器端套接字:指定监听的接口
  16. ServerSocket serverSocket = new ServerSocket(8888);
  17. System.out.println("服务端建立监听");
  18. // 监听,等待客户端请求,并愿意接收连接
  19. socket = serverSocket.accept();
  20. // 获取socket的输出流,并使用缓冲流进行包装
  21. bw = new BufferedWriter(new
  22. OutputStreamWriter(socket.getOutputStream()));
  23. // 向客户端发送反馈信息
  24. bw.write("hhhh");
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. } finally {
  28. // 关闭流及socket连接
  29. if (bw != null) {
  30. try {
  31. bw.close();
  32. } catch (IOException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. if (socket != null) {
  37. try {
  38. socket.close();
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. }
  45. }

客户端

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.net.InetAddress;
  5. import java.net.Socket;
  6. /**
  7. * 最简单的Socket客户端
  8. * @author Administrator
  9. */
  10. public class BasicSocketClient {
  11. public static void main(String[] args) {
  12. Socket socket = null;
  13. BufferedReader br = null;
  14. try {
  15. /*
  16. * 创建Scoket对象:指定要连接的服务器的IP和端口而不是自己机器的
  17. * 端口。发送端口是随机的。
  18. */
  19. socket = new Socket(InetAddress.getLocalHost(), 8888);
  20. //获取scoket的输入流,并使用缓冲流进行包装
  21. br = new BufferedReader(new
  22. InputStreamReader(socket.getInputStream()));
  23. //接收服务器端发送的信息
  24. System.out.println(br.readLine());
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. } finally {
  28. // 关闭流及socket连接
  29. if (br != null) {
  30. try {
  31. br.close();
  32. } catch (IOException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. if (socket != null) {
  37. try {
  38. socket.close();
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. }
  45. }

双向通信

服务器端

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. public class Server {
  9. public static void main(String[] args){
  10. Socket socket = null;
  11. BufferedReader in = null;
  12. BufferedWriter out = null;
  13. BufferedReader br = null;
  14. try {
  15. //创建服务器端套接字:指定监听端口
  16. ServerSocket server = new ServerSocket(8888);
  17. //监听客户端的连接
  18. socket = server.accept();
  19. //获取socket的输入输出流接收和发送信息
  20. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  21. out = new BufferedWriter(new
  22. OutputStreamWriter(socket.getOutputStream()));
  23. br = new BufferedReader(new InputStreamReader(System.in));
  24. while (true) {
  25. //接收客户端发送的信息
  26. String str = in.readLine();
  27. System.out.println("客户端说:" + str);
  28. String str2 = "";
  29. //如果客户端发送的是“end”则终止连接
  30. if (str.equals("end")){
  31. break;
  32. }
  33. //否则,发送反馈信息
  34. str2 = br.readLine(); // 读到\n为止,因此一定要输入换行符!
  35. out.write(str2 + "\n");
  36. out.flush();
  37. }
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. } finally {
  41. //关闭资源
  42. if(in != null){
  43. try {
  44. in.close();
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. if(out != null){
  50. try {
  51. out.close();
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. if(br != null){
  57. try {
  58. br.close();
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. if(socket != null){
  64. try {
  65. socket.close();
  66. } catch (IOException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. }
  71. }
  72. }

客户端

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.io.OutputStreamWriter;
  6. import java.net.InetAddress;
  7. import java.net.Socket;
  8. import java.net.UnknownHostException;
  9. public class Client {
  10. public static void main(String[] args) {
  11. Socket socket = null;
  12. BufferedReader in = null;
  13. BufferedWriter out = null;
  14. BufferedReader wt = null;
  15. try {
  16. //创建Socket对象,指定服务器端的IP与端口
  17. socket = new Socket(InetAddress.getLocalHost(), 8888);
  18. //获取scoket的输入输出流接收和发送信息
  19. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  20. out = new BufferedWriter(new
  21. OutputStreamWriter(socket.getOutputStream()));
  22. wt = new BufferedReader(new InputStreamReader(System.in));
  23. while (true) {
  24. //发送信息
  25. String str = wt.readLine();
  26. out.write(str + "\n");
  27. out.flush();
  28. //如果输入的信息为“end”则终止连接
  29. if (str.equals("end")) {
  30. break;
  31. }
  32. //否则,接收并输出服务器端信息
  33. System.out.println("服务器端说:" + in.readLine());
  34. }
  35. } catch (UnknownHostException e) {
  36. e.printStackTrace();
  37. } catch (IOException e) {
  38. e.printStackTrace();
  39. } finally {
  40. // 关闭资源
  41. if (out != null) {
  42. try {
  43. out.close();
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. if (in != null) {
  49. try {
  50. in.close();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. if (wt != null) {
  56. try {
  57. wt.close();
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. if (socket != null) {
  63. try {
  64. socket.close();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }
  71. }

聊天室

服务器端

  1. package cn.menglangpoem.chat;
  2. import java.io.DataInputStream;
  3. import java.io.DataOutputStream;
  4. import java.io.IOException;
  5. import java.net.ServerSocket;
  6. import java.net.Socket;
  7. import java.util.List;
  8. import java.util.concurrent.CopyOnWriteArrayList;
  9. /**
  10. * 聊天室服务器
  11. */
  12. public class Server {
  13. //准备容器,存储客户端
  14. private static List<Chanel> list = new CopyOnWriteArrayList<>();
  15. //主函数
  16. public static void main(String[] args) throws IOException {
  17. int num = 0;
  18. //创建服务器
  19. ServerSocket server = null;
  20. try {
  21. server = new ServerSocket(8888);
  22. System.out.println("服务器已启动,端口号---->8888");
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. while(true)
  27. {
  28. //接收客户端
  29. Socket client = server.accept();
  30. num++;
  31. System.out.println(num+"个服务器已连接");
  32. //存储到容器
  33. Chanel chanel = new Chanel(client);
  34. list.add(chanel);
  35. //开启线程
  36. new Thread(chanel).start();
  37. }
  38. }
  39. //信号通道
  40. static class Chanel implements Runnable{
  41. private Socket clinet = null;//客户端
  42. private boolean flag = true;//控制运行
  43. private DataInputStream clientR = null; //读信息
  44. private DataOutputStream clientW = null;//写信息
  45. private String name; //客户端姓名
  46. public Chanel(Socket clinet) {
  47. this.clinet = clinet;
  48. //初始化
  49. try {
  50. this.clientR = new DataInputStream(clinet.getInputStream());
  51. this.clientW = new DataOutputStream(clinet.getOutputStream());
  52. this.name = clientR.readUTF();
  53. this.send("欢迎来到聊天室!");
  54. } catch (IOException e) {
  55. //e.printStackTrace();
  56. System.out.println("初始化失败!");
  57. flag = false;
  58. }
  59. }
  60. @Override
  61. public void run() {
  62. while(flag)
  63. {
  64. sendOthers();
  65. }
  66. }
  67. //发送
  68. private void send(String msg)
  69. {
  70. //判断是否为空
  71. try {
  72. //System.out.println("send ---- "+msg);
  73. clientW.writeUTF(msg);
  74. clientW.flush();
  75. } catch (IOException e) {
  76. //e.printStackTrace();
  77. System.out.println("发送失败!");
  78. flag = false;
  79. }
  80. }
  81. //接收
  82. private String receive()
  83. {
  84. String msg = null;
  85. try {
  86. msg = clientR.readUTF();
  87. } catch (IOException e) {
  88. //e.printStackTrace();
  89. System.out.println("接收失败!");
  90. flag = false;
  91. }
  92. return msg;
  93. }
  94. //发送群消息
  95. private void sendOthers()
  96. {
  97. String msg = receive();
  98. for(Chanel other: list)
  99. {
  100. if(other == this)
  101. continue;
  102. else
  103. {
  104. other.send(this.name+"说"+msg);
  105. }
  106. }
  107. }
  108. }
  109. }

客户端

  1. package cn.menglangpoem.chat;
  2. import java.io.DataInputStream;
  3. import java.io.DataOutputStream;
  4. import java.io.IOException;
  5. import java.net.Socket;
  6. import java.util.Scanner;
  7. /**
  8. * 聊天客户端
  9. */
  10. public class Client {
  11. public static void main(String[] args) throws IOException {
  12. //连接服务器
  13. Socket server = new Socket("localhost",8888);
  14. //启动线程
  15. new Thread(new Send(server)).start();
  16. new Thread(new Receive(server)).start();
  17. System.out.println("请输入昵称");
  18. }
  19. //接收信息
  20. static class Receive implements Runnable{
  21. private Socket server = null;
  22. private boolean flag = true;
  23. DataInputStream serverR = null;
  24. //构造函数
  25. public Receive(Socket server) {
  26. //初始化
  27. this.server = server;
  28. try {
  29. this.serverR = new DataInputStream(server.getInputStream());
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. flag = false;
  33. }
  34. }
  35. @Override
  36. public void run() {
  37. while (flag)
  38. {
  39. System.out.println(receive());
  40. }
  41. }
  42. private String receive()
  43. {
  44. String msg = null;
  45. try {
  46. msg = serverR.readUTF();
  47. } catch (IOException e) {
  48. //e.printStackTrace();
  49. System.out.println("接收信息失败!");
  50. flag = false;
  51. }
  52. return msg;
  53. }
  54. }
  55. //发送信息
  56. static class Send implements Runnable{
  57. private Socket server = null;
  58. private DataOutputStream serverW = null;
  59. private boolean flag = true;
  60. public Send(Socket server) {
  61. this.server = server;
  62. try {
  63. serverW = new DataOutputStream(server.getOutputStream());
  64. } catch (IOException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. //线程体
  69. @Override
  70. public void run() {
  71. while (flag)
  72. send();
  73. }
  74. //发送函数
  75. private void send()
  76. {
  77. Scanner scanner = new Scanner(System.in);
  78. String msg = scanner.next();
  79. try {
  80. serverW.writeUTF(msg);
  81. serverW.flush();
  82. } catch (IOException e) {
  83. e.printStackTrace();
  84. System.out.println("发送信息失败!");
  85. flag = false;
  86. }
  87. }
  88. }
  89. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/850727
推荐阅读
相关标签
  

闽ICP备14008679号