BIO

The client

package org.example.net.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;

public class BioClient {
    public static void main(String[] args) throws IOException {
        int port = 8888;
        String ip = "127.0.0.1";
        Socket socket = new Socket(ip, port);
        // socket.setSoTimeout(10 * 1000);
        BufferedReader in = null;
        PrintWriter out = null;
        System.out.println("Client started!");
        try {
            Scanner scanner = new Scanner(System.in);
            while (true) {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
                String input = scanner.nextLine();
                out.println(input);
                if (input.equals("exit")) break;
                System.out.println("Input complete, wait for a response.");
                String data = in.readLine();
                System.out.println("That's it. There's a response.");
                System.out.println(new Date() + "The client receives the response from the server :"+ data); }}catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(in ! =null) {
                    in.close();
                }
                if(out ! =null) {
                    out.close();
                }
                socket.close();
            } catch(Exception e) { e.printStackTrace(); }}}}Copy the code

The service side

package org.example.net.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;

public class BioServer {
    public static void main(String[] args) throws IOException {
        int port = 8888;
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("Server up!");
        while (true) {
            /* try { TimeUnit.MINUTES.sleep(1); System.out.println(" server wakes up from sleep "); } catch (InterruptedException e) { e.printStackTrace(); } * /
            Socket socket = serverSocket.accept();
            System.out.println("Server received connection");
            new Thread(newSocketHandle(socket)).start(); }}}class SocketHandle implements Runnable {
    Socket socket;


    SocketHandle(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run(a) {
        BufferedReader in = null;
        PrintWriter out = null;
        Scanner scanner = new Scanner(System.in);
        try {
            while (true) {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream(), true);
                String data = in.readLine();
                if (data.equals("exit")) {
                    break;
                }
                System.out.println(new Date() + "The server receives a message from the client: + data);

                System.out.println("Server is ready to send message.");
                out.println(scanner.nextLine());
                System.out.println("The server is finished receiving and sending messages."); }}catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(in ! =null) {
                    in.close();
                }
                if(out ! =null) {
                    out.close();
                }
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("Current thread terminated"); }}Copy the code

Test scenarios

  • Normal execution effect

The client sends data twice, the server returns once, and finally the client sends exit, the server reads it, and then the client closes the connection.

  • What if the server sleeps until it accepts? What is the connection state before it accepts?

Before accept, the connection is established. Before accept, the “connection” is placed in the server operating system’s full connection queue. After the sleep, the server can consume the connection and then process the read and write operations of the connection as normal.

  • If “Connect” is on the server’s full connection queue and the client is ready to send data, will the server return an ACK?

The server can return an ACK, which is returned by the OPERATING system’s TCP/IP stack.

  • If the data is sent successfully, the server cannot process the request because the server has not accepted the connection, and the client waits for the response time out, and the client actively closes the connection, can the server still consume the connection in the full connection queue?

Server consumption is not affected because the connection is already in the full connection queue. Description The operating system did not delete the FIN from the full connection queue after receiving the FIN from the client.

  • If the consumption succeeds, can the server still read the request data that has responded to the ACK? If it reads successfully, can it write successfully to return the result after processing the request data?

The server can read the data normally, but the RST will discard the data after the client OS receives the response.

In the figure above, although the server is in the sleep state before accept, the client can still successfully shake hands for three times and send data. After reading data from the server times out, the client closes the connection and sends the FIN. After the server accepts the connection, it can read the data and send the response, but is RST by the client.