Java Socket call analysis with the underlying Linux Socket

This paper analyzes the API from Java Socket to call the chain of Linux Socket API, so that to explore how Java Socket is provided using the Linux system calls to implement the corresponding function.

Java Socket API sample code

Firstly, a write Java Socket API simple Hello / Hi use code example.

 //服务端
1
ServerSocket server = new ServerSocket(8000); 2 Socket client = server.accept(); 3 InputStream in = client.getInputStream(); 4 byte[] bytes = new byte[1024]; 5 int len = in.read(bytes); 6 String data = new String(bytes, 0 , len); 7 System.out.println("接收客户端消息:" + data); 8 9 OutputStream out = client.getOutputStream(); 10 out.write("Hi".getBytes()); 11 client.close();
 //客户端
1
Socket client = new Socket("localhost", 8000); 2 OutputStream out = client.getOutputStream(); 3 String msg = "Hello"; 4 out.write(msg.getBytes()); 5 6 InputStream in = client.getInputStream(); 7 byte[] bytes = new byte[1024]; 8 int len = in.read(bytes); 9 String s = new String(bytes, 0, len); 10 System.out.println("接收服务端响应信息:" + s); 11 client.close();

 

Create a server and receive connector

Socket server to create and call accept to receive a connection request from a client by calling ServerSocket constructor.

create

We can be found through the source code debugging, ServerSocket constructor, call the bind method of the ServerSocket. Acquired AbstractPlainSocketImpl object and call the bind method of the object two important methods bind and listen. Respectively, bind and listen AbstractPlainSocketImpl method, the call to the native method socketBind and socketListen. To understand these two native methods in the end what the use of a Linux system calls to implement functionality, we continue to view the native jdk source method provided, can be found in the native / java / net / PlainSocketImpl.c method Java_java_net_PlainSocketImpl_socketBind and Java_java_net_PlainSocketImpl_socketListen. In the method Java_java_net_PlainSocketImpl_socketBind can clearly see calling NET_Bind to bind, and NET_Bind achieve in native / java / net / net_util_md.c, ultimately bind call to bind through the system. In the method can also be seen Java_java_net_PlainSocketImpl_socketListen called JVM_Listen to port monitoring, and JVM_Listen implemented in jvm.c, simply call the listen system call monitoring. The following figure shows the server to create almost call flow process.

 

Connect the receiver

serverSocket to accept calls waiting to receive the connection. Its internal call chain and create a similar, namely during the call implAccept method, and getting a AbstractPlainSocketImpl object and calls the accept method of the object, in AbstractPlainSocketImpl accept method, the method further called native socketAccept. The method can be found in native native / java / net / PlainSocketImpl.c are embodied as Java_java_net_PlainSocketImpl_socketAccept, wherein the method further calls NET_Accept linux_close.c in, and eventually a call accept system call to wait to receive the connection.

 

The client creates

Create Create client and server is relatively simple in comparison. In the constructor Socket, if we specify a local InetAdress and localPort will first call the bind method to bind to the designated port, bind specific processes and server bind process similar to the above. But usually we do not the client's local address specified, it does not bind the implementation process, but directly connect the process. In Socket connect method, the first will get AbstractPlainSocketImpl object and call connect the object, and then call the native method socketConnect. According to the above jdk native analysis process, we can be found in the call chain socketConnect (outside parentheses method, in brackets file), Java_java_net_PlainSocketImpl_socketConnect (PlainSocketImpl.c) -> NET_Select (linux_close.c) -> select (sys_call)

 

Read and write data

Whether the client or the server may be required to read and write data, and its implementation is the same.

Data read

Java Socket直接通过获取SocketInputStream,调用read方法来进行数据读入。read方法进而调用了socketRead,在socketRead方法中又调用了native方法socketRead0。native方法socketRead0的实际实现为native/java/net/SocketInputStream.c中的Java_java_net_SocketInputStream_socketRead0,该方法继而又调用了linux_close.c中的NET_Read,最终调用了系统调用recv来进行数据读入。

数据写

Java Socket直接通过获取SocketOutputStream,调用write方法来进行数据写入。write方法进而调用了socketWrite,在socketWrite方法中又调用了native方法socketWrite0。native方法socketWrite0的实际实现为native/java/net/SocketOutputStream.c中的Java_java_net_SocketOutputStream_socketWrite0,该方法继而又调用了linux_close.c中的NET_Send,最终调用了系统调用send来进行数据写入。

 

关闭

当通讯双方通讯结束时,需要关闭socket。在Java代码中可以直接调用Socket的close来进行关闭。Socket的close方法会进一步调用AbstractPlainSocketImpl的close方法,继而调用native方法socketClose0。可在jdk提供的native源码中找到该native方法的调用链,Java_java_net_PlainSocketImpl_socketClose0(PlainSocketImpl.c)->NET_SocketClose(linux_close.c)->closefd(sys_call).

Guess you like

Origin www.cnblogs.com/fiveFish/p/12005960.html