1

他のソケットが閉じているときにソケットから読み取ろうとすると、異なる結果が得られます。

私は2つのソケットAとBを持っています。

1)B が A にデータを送信 --> A がデータを読み取った --> A が閉じる --> B が A からデータを読み取ろうとすると、-1 (または EOF) が取得されます。

2)B が A にデータを送信 --> データを読み取る前に A が閉じる --> B が A から読み取ろうとすると、例外がスローされます (java.net.SocketException "Software due to connection abort.")

私の質問が理解できない場合は、ご容赦ください。コードをご覧ください

サーバー.java

import java.io.*;
import java.net.*;


class SocketCloser extends Thread
{
    private Socket c;
    public SocketCloser(Socket c) {
        this.c = c;
    }

    public void run()  {

        try{
            this.c.close();
        } catch (Exception e) {}
    }
}


public class Server
{
    public static void main(String argv[]) throws Exception {
        ServerSocket listen = new ServerSocket(6789);

        Socket socket = listen.accept();
        SocketCloser sc = new SocketCloser(socket);
        InputStream is = socket.getInputStream();
        // uncomment below line to get "Software caused connection abort" on client
        //sc.start();
        try {
            Thread.sleep(1000);
            int i = is.read();
            System.out.println("read returned: " + i);
            socket.close();
        } catch (Exception e) {
            System.out.println(e.toString() + " thrown");
        }
    }
}

クライアント.java

import java.io.*;
import java.net.*;

public class Client
{
    public static void main(String argv[])
    {
        Socket cSocket;
        try {
            cSocket = new Socket("localhost", 6789);
            InputStream is = cSocket.getInputStream();
            OutputStream os = cSocket.getOutputStream();
            Thread.sleep(1000);
            os.write(200);
            Thread.sleep(1000);
            int i = is.read();
            System.out.println("read returned: " + i);
            cSocket.close();
        } catch (Exception e) {
            System.out.println(e.toString() + " thrown");
        }
    }
}

あるケースでは例外があり、別のケースでは -1 がある理由を誰かが理解するのを手伝ってくれませんか。興味深いことに、Linux では両方のケースで -1 が返されました。

4

2 に答える 2

0

1)B が A にデータを送信 --> A がデータを読み取った --> A が閉じる --> B が A からデータを読み取ろうとすると、-1 (または EOF) が取得されます。

同意します。何を期待していましたか?これは予期される動作です。

2)B が A にデータを送信 --> データを読み取る前に A が閉じる --> B が A から読み取ろうとすると、例外がスローされます (java.net.SocketException "Software due to connection abort.")

同意します。これは、この不適切な状況で予想される動作の 1 つです。何を期待していましたか?

私の質問が理解できない場合は、ご容赦ください。

ここで理解するのに疑問はありません。あなたは質問をしていません。データを送信せずにソケットを閉じると、ピアはデータを受信せずに EOS を取得します。ピアが送信中にソケットを閉じると、ピアは例外を受け取ります。システムは設計どおりに機能しています。

于 2012-12-08T11:47:37.143 に答える
0

1) B が接続を確立したため、A は CLOSE_WAIT に進みます。B が接続を閉じるまで、その状態になります。読み取るものがないため、B の InputStream に対する read() 呼び出しは -1 を返します。

2) A は受け入れ呼び出しでブロックされます。他のスレッドがソケットを閉じようとしていますが、accept がブロックしているためできません。B が接続すると、ブロック解除を受け入れると、ソケットが完全に閉じます。B が読み取ろうとすると、ソケットが存在しないため、例外が発生します。

少し簡略化していますが、それが要点です。

于 2012-12-08T07:50:20.810 に答える