Postura correta de fechamento do soquete

O soquete java corresponde ao tcp no protocolo de rede. O handshake de três vias tcp, quatro mãos acenadas e o status em 11 não são mencionados aqui. Não sei se você não presta atenção ao usar o soquete. Relate erros para várias exceções.
Por exemplo:

java.net.SocketException:socket is closed
错误提示的出现场景:
自己主动关闭了socket,但是之后还从里面读写数据


Software caused connection abort: socket write error
错误提示的出现场景:
对方已经关闭socket,依旧向对方写数据


connection reset (by peer)
错误提示出现的场景:
一端socket被关闭,另一端仍然发送数据,发送的第一个数据包 connection reset by peer
一端socket退出,退出时为关闭连接,另一端读数据 connection reset

Portanto, ao usar um soquete, você precisa concordar com as condições de ambas as partes para concluir a leitura e a gravação e, em seguida, fechar os fluxos de entrada e saída:

socket.shutdownInput();
socket.shutdownOutput();

Ou seja, quando uma parte termina de gravar, chame shutdownOutput para fechar o fluxo de saída, o método de leitura da outra parte retornará -1, a outra parte saberá que você terminou de escrever, a outra parte pode fechar o fluxo de entrada e esperar que a outra parte termine de escrever depois de chamar shutdownOutput Quando você chama shutdownInput novamente, ambas as partes normalmente fecham os fluxos de entrada e saída e o soquete não será anormal neste momento.
A seguir está um exemplo de interação de soquete:
lado do servidor

public class OioServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("socket = " + socket);
            new Thread(() -> {
                try {
                    InputStream in = socket.getInputStream();
                    OutputStream out = socket.getOutputStream();
                    out.write("hello! I get your message that is follow".getBytes(Charset.forName("UTF-8")));
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) != -1) {
                        System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
                        out.write(buf, 0, len);
                    }
                    out.write("\n end \n".getBytes(Charset.forName("UTF-8")));
                    out.flush();
                    socket.shutdownInput();
                    socket.shutdownOutput();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

Lado do cliente

public class OioClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 8080);
        InputStream in = socket.getInputStream();
        new Thread(() -> {
            BufferedInputStream bufferIn = new BufferedInputStream(in);
            byte[] buf = new byte[1024];
            try {
                int len;
                while ((len = bufferIn.read(buf)) != -1) {
                    System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
            try {
                socket.shutdownInput();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }).start();
        OutputStream out = socket.getOutputStream();
        int cout = 10;
        while (cout-- > 0) {
            out.write(("this time is " + System.currentTimeMillis() + "\n").getBytes("UTF-8"));
        }
        socket.shutdownOutput();
    }
}


 

Acho que você gosta

Origin blog.csdn.net/bj_chengrong/article/details/103815517
Recomendado
Clasificación