ソケットの正しい閉姿勢

Javaソケットは、ネットワークプロトコルのTCPに対応しています。TCP3ウェイハンドシェイク、4つのウェイブハンド、11のステータスについては、ここでは触れていません。ソケットを使用するときに注意を払わないかどうかはわかりません。エラーをさまざまな例外に報告します。
例えば:

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

したがって、ソケットを使用する場合は、両方の当事者が読み取りと書き込みを完了し、次に入力ストリームと出力ストリームを閉じるための条件に同意する必要があります。

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

つまり、一方のパーティが書き込みを終了したら、shutdownOutputを呼び出して出力ストリームを閉じ、もう一方のパーティのreadメソッドは-1を返し、もう一方のパーティは書き込みが完了したことを認識し、もう一方のパーティは入力ストリームを閉じ、shutdownOutputを呼び出した後、他方のパーティが書き込みを完了するのを待つことができます。 shutdownInputを再度呼び出すと、通常、両方のパーティが入力ストリームと出力ストリームを閉じます。このとき、ソケットは異常ではありません。
以下は、ソケットの相互作用の例です。
サーバー側

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();
        }
    }
}

クライアント側

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();
    }
}


 

おすすめ

転載: blog.csdn.net/bj_chengrong/article/details/103815517