java socket套接字编程入门
服务之间的通信,有基于应用层的http,也有基于底层的tcp协议。通信会涉及到数据的发送、接收以及拆组包,信息控制等网络流程。网络分层分为两种:五层、七层。
java socket 套接字编程指的是编写跨多台计算机执行的程序。在这些计算机之间都是通过网络进行连接。
有两种协议用于套接字开发:UDP(User Datagram Protocol)用户数据报协议和TCP(Transfer Control Protocol)传输控制协议。因此socket是属于传输层。
UDP和TCP的主要区别:UDP是无连接传输模式,这意味着客户端与服务端没有会话。 TCP是面向连接传输模式,意味着必须首先要在客户端与服务端建立一个连接(排他性连接),以便于通信。
UDP没有会话,没有办法保证通信内容的完整性,因有可能会出现丢包情况。没有建立会话,因此每次通信更快传输更多,使用于就算偶尔丢包也能正常使用的场景。
TCP通过会话的方式来保证内容的完整性,会话的过程自然会涉及到创建连接,监听,接收处理,返回等流程。
清楚流程,再来看下各端代码逻辑。
server服务端
public static void main(String[] args) { try { //1、建立服务连接 //服务运行于特定的服务器中并绑定一个socket 端口 ServerSocket serverSocket = new ServerSocket(9090); //2、创建socket并监听 //监听socket创建的连接并接受到它,此为阻塞方法,直到连接创建 Socket socket = serverSocket.accept(); //接收传输过来的数据 //设置每次接收块的大小 char[] data = new char[10]; BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); int len = 0; //3、接收数据 //处理传输数据大于接收块的容量 //读取的字符数,如果已到达流的末尾则为-1 while ((len = br.read(data)) != -1){ System.out.println(String.valueOf(data, 0, len)); } //关闭 //顺序:按打开的顺序进行反序关闭 br.close(); socket.close(); serverSocket.close(); } catch (Exception e){ e.printStackTrace(); } }
client客户端
public static void main(String[] args) throws IOException { //创建socket连接 Socket socket = new Socket("127.0.0.1", 9090); //发送数据到服务端 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write("这是一个测试"); writer.flush();//刷新缓冲流,把write提交进去,不然服务端没接收到内容 // 关闭连接,否则服务端抛出:java.net.SocketException: Connection reset
//通知服务端,客户端发送数据完成。 writer.close(); }
关于java.net.SocketException: Connection reset。 谈不上通知,是一种标识,让服务端知道发送数据已经完成。服务端是通过阻塞的方式来监听和接收数据,在整个过程中有二处阻塞:1、监听accept();2、读取read(data)。
如果客户端没有close(),服务端read() 并不知道是否结束,但随着客户main主线程运行完成,就会强行切断关闭此连接,因此才会有此异常抛出。