socket通信详解

来源:互联网 发布:淘宝有哪些靠谱的日代 编辑:程序博客网 时间:2024/05/22 01:57

本文详细讲解socket的通信过程,便于理解,不对的地方请留言指出。

本片源于一篇中文字符乱码的讲解,请移步:

java socket通信时,中文字符乱码的一个解决方法 - mecho的专栏 - 博客频道 - CSDN.NET
点击打开链接

通信吗,就是双方收发消息,那么它具体怎么实现的呢?下面分析一下

先上代码:

服务端:

package helloword2;import java.io.*;  import java.net.*;public class HelloWord {public static void main(String[] args) {        System.out.println("Server");                  ServerSocket serverSocket = null;          Socket clientSocket = null;          int connects = 0;          try {              serverSocket = new ServerSocket(82, 5);     //端口:82,最大链接数:5                //最多连接10次              while(connects < 10) {                  connects++;                  System.out.println("--------------------等待连接--------------------------");                  clientSocket = serverSocket.accept();   //等待client连接                  System.out.println("第 " + connects + " 次连接");                  ServiceClient(clientSocket);              }                serverSocket.close();          } catch(IOException ioe) {              System.out.println("Error: " + ioe);          } } public static void ServiceClient(Socket client) throws IOException {          System.out.println("已链接");                    InputStreamReader inSR = null;          OutputStreamWriter outSW = null;          try {              //读取数据              inSR = new InputStreamReader(client.getInputStream(), "UTF-8");              BufferedReader br = new BufferedReader(inSR);                            outSW = new OutputStreamWriter(client.getOutputStream(), "UTF-8");              BufferedWriter bw = new BufferedWriter(outSW);                            String str = "";              System.out.println("。。。。。有运行。。。");                        while((str = br.readLine()) != null) {              //readLine()函数是阻塞的,链接建立后,等待消息输入,每次接受消息从这里开始执行,client中断即socket.close后就从while循环后面开始执行                str = str.trim();  //                System.out.println("str==:" +br.readLine());                  System.out.println("收到客户端消息:" + str);                                    bw.write("已收到信息:" + str + " \r\n"); //向客户端反馈消息,加上分行符以便客户端接收                  bw.flush();              }              System.out.println("============服务器端====");            } finally {              //System.out.println("Cleaning up connection: " + client);              inSR.close();              outSW.close();              client.close();              System.out.println("*****服务端*************关闭流------" );          }          System.out.println("已断开");      }  }

说明:

运行服务端:run as Java Application


服务端运行到clientSocket = serverSocket.accept();阻塞函数,等待客户端链接

客户端代码:

package hellword3;import java.io.*;  import java.net.*; public class Example {public static void main(String[] args) throws Exception{ System.out.println("Client");          try {              Socket clientSocket = new Socket("192.168.0.115", 82);              System.out.println("Client1:" + clientSocket);                DataInputStream dataIS = new DataInputStream(clientSocket.getInputStream());              InputStreamReader inSR = new InputStreamReader(dataIS, "UTF-8");              BufferedReader br = new BufferedReader(inSR);                            DataOutputStream dataOS = new DataOutputStream(clientSocket.getOutputStream());              OutputStreamWriter outSW = new OutputStreamWriter(dataOS, "UTF-8");              BufferedWriter bw = new BufferedWriter(outSW);                //输入信息              byte bytes[] = new byte[100];              while(true) {                  System.out.println("-----等待------输入--------");                  System.in.read(bytes);                  String str = new String(bytes);                  str = str.trim();                  if (str.equals("exit")) {                      break;                  }                    //发送数据                  bw.write(str + "\r\n");     //加上分行符,以便服务器按行读取                  bw.flush();                                                      //接收数据                  while((str = br.readLine()) != null) {                      str = str.trim();                      System.out.println("服务器回复:" + str);                      break;                  }                  System.out.println("===while 内------" );             }                            inSR.close();              dataIS.close();              dataOS.close();              clientSocket.close();             System.out.println("========客户端==关闭流------" );  //while(true) 永远不会被执行吗?        } catch(UnknownHostException uhe) {              System.out.println("Error:" + uhe.getMessage());          } catch(ConnectException ce) {              System.out.println("Error:" + ce.getMessage());          } catch(IOException ioe) {              System.out.println("Error:" + ioe.getMessage());          } finally {          }    }}

说明:

运行客户端:run as Java Application


这时,服务端输出:


服务端运行到while循环前等待客户端发来的消息。

客户端依次输入hello,你好,exit,输入时不要忘记回车

客户端l输出log:


服务器端输出:



解释:当链接建立后,服务器端消息是从这里开始运行的 while((str = br.readLine()) != null) { }一直循环,有消息就执行出来,


   客户端输入exit时,客户端跳出while循环,执行 clientSocket.close(); 就是关闭socket流:


sever接到client端socket流关闭后,服务端也跳出while循环,

继续向下执行:


socket是端到端通信只要一端关了,另一端也自动关了,(任何一边关了,就都关了)线程不等待,会执行下去,顺序:

服务端开户—等待—链接—执行收发消息—往下执行。

解释一下:服务端运行后会等待客户端发来的socket请求链接:serverSocket.accept();链接建立以后,建立里流通道,等待客户端发来的消息: while((str = br.readLine()) != null),循环内会执行收发消息,socket.close以后,继续往下执行,及执行while后面的内容。直到执行完一次链接,等待下次:


注意:br.readLine()是阻塞函数(就是说它读完了一条信息在那等着,不往下执行), 要流关闭的时候 才会返回null,才会跳出循环,不然就等着,程序不往下走,这和QQ聊天时一个道理,你发一句,它接收一句,你不发,它就等着,你关闭QQ,它才关闭,往下执行,,另外其他流也可以收发消息,比如:发消息

DataOutputStream

output = new DataOutputStream(socket.getOutputStream());output.writeUTF("send data");
PrintWriter 

 pw = new PrintWriter(socket.getOutputStream());// 要输出的数据流  pw.println(str);  pw.flush();

over。




0 0