socket通信详解

本文详细讲解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。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值