This is the 15th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

The other day I introduced some concepts of computer networking and introduced several protocols. Let’s talk about Socket programming in Java. How do servers and clients communicate?

We know that in TCP/IP protocol cluster, TCP and UDP protocols are at the transport layer, and the application layer communicates based on the transport layer. Socket can be regarded as the implementation of TCP and UDP. When programming, it depends on whether the service is selected to use TCP or UDP. Today’s main talk is based on TCP communication Socket implementation. If you’re not familiar with TCP. You can read this article.

Java provides two classes for TCP: the Socket class and the ServerSocket class. A Socket instance represents a client of the TCP connection, and a ServerSocket instance represents a server of the TCP connection. Generally, in TCP Socket programming, there are multiple clients and only one server. The client TCP sends connection requests to the server TCP, and the ServerSocket instance on the server listens for TCP connection requests from the client and creates a new Socket instance for each request. Because the server will block when it calls Accept () to wait for connection requests from the client, The code does not proceed until it receives a connection request from the client, so start a thread for each Socket connection. The server handles both ServerSocket instances and Socket instances, while the client only needs to use the Socket instance.

In addition, each Socket instance is associated with an InputStream and an OutputStream object. We send data by writing bytes to the Socket’s OutputStream and receive data from the InputStream.

Ok, the above description may be a bit confusing, but let’s look at a demo. Use Socket to achieve a simple interaction, in the server side using multi-threading to handle requests.

The client implementation is as follows:

public class Client {  
    public static void main(String[] args) throws IOException {  
        Socket socket = null;  
        PrintWriter pw = null;  
        BufferedReader br = null;  
        try {  
            // Create a Socket object to specify the server address and port to connect to
            socket = new Socket("localhost".6688);  
  
            // After the connection is established, request information is sent to the server through Socket output
            pw = new PrintWriter(socket.getOutputStream());  
            pw.write("Hello , server . I'm Client !");  
            pw.flush();  
            socket.shutdownOutput();  
  
            // Get the response information from the server side through the input stream;
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
            String info = null;  
                while((info = br.readLine()) ! =null){  
                    System.out.println("Server returns message:"+ info); } socket.shutdownInput(); Error handling and closing resources after ---- omit -----}}Copy the code

The server-side implementation is as follows:

public class Server {  
    public static void main(String[] args) throws IOException {  
        Socket socket = null;  
        try {  
            // Create a ServerSocket object and bind the listener port
            ServerSocket serverSocket = new ServerSocket(6688);  
            while(true) {// Listen for client requests through the Accept () method
                socket =serverSocket.accept();  
                ServerThread serverThread = newServerThread(socket); serverThread.start(); }}}Copy the code

Thread implementation is as follows:

public class ServerThread extends Thread {  
    Socket socket = null;  
    BufferedReader br = null;  
    PrintWriter pw = null;  
  
    public ServerThread(Socket socket){  
        this.socket = socket;  
    }  
  
    @Override  
    public void run(a) {  
        try {  
            // After the connection is established, the request message MSG sent by the client is read through the input stream
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
            StringBuffer msg = new StringBuffer();  
            String info = null;  
            while((info = br.readLine()) ! =null){  
                msg.append(info);  
            }  
            System.out.println("Server received ["+ socket.getInetAddress()+"] message [" + msg+"]");  
            socket.shutdownInput();  
  
            // Send information to the client through the output
            pw = new PrintWriter(socket.getOutputStream());  
            pw.write(" success !"); pw.flush(); socket.shutdownOutput(); }}}Copy the code

Summarize the steps of Socket TCP combat.

Server side:

(1) Create the ServerSocket object and bind the listening port; (2) Listen to client requests through accept() method; (3) After the connection is established, the request information sent by the client is read through the input stream; (4) Send corresponding information to the client through the output;

(5) Close the response resource.

Client:

(1) Create a Socket object to indicate the address and port of the server to be connected; (2) After the connection is established, request information is sent to the server through the output; (3) Obtain the response information returned by the server through the input stream;

(4) Close the response resource.

Note:

1 First executes the server-side code.

2 By default, the server waits for the connection request from the client.

The above is just a very basic case, this is just the tip of the iceberg of Socket programming.

4 There are many other areas that can be optimized, such as the optimization of server side parameters, such as buffer size to accept data, maximum waiting time for client connections, using thread pool to process requests, etc.