0

再接続の処理方法を理解できるように、プロトタイプのクライアントとサーバーを作成しています。サーバーはサーバーソケットを作成し、永久にリッスンする必要があります。クライアントは接続してデータを送信し、ソケットを閉じることができますが、「完了して終了しました」というタイプのメッセージをサーバーに送信しません。このため、リモートクライアントが閉じているため、サーバーはサーバーがaEOFExceptionを実行するとを取得します。readByte()のエラーハンドラではEOFException、ソケットを閉じて新しいソケットを開きます。

問題は次のとおりです。クライアントは、ソケット/入力ストリーム/出力ストリームを正常に開いた後でもSocketWriteError、呼び出しを行うとを取得することがあります。outputStream.write()これらのソケットを開閉する頻度と関係があるかもしれません。興味深い点の1つは、クライアントがクラップアウトする前に任意の数の書き込み/クローズ/再接続を実行することです。最初の再接続時に機能しなくなる場合もあれば、が表示されるまでに50回の再接続が必要な場合もありSocketWriteErrorます。

クライアント側のエラーは次のとおりです。

java.net.SocketException:ピアによる接続のリセット:ソケット書き込みエラー
       java.net.SocketOutputStream.socketWrite0(ネイティブメソッド)で
       java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)で
       java.net.SocketOutputStream.write(SocketOutputStream.java:115)で
       bytebuffertest.Client.main(Client.java:37)で

コードのスニペットは次のとおりです。

サーバ:

public static void main(String[] args)
{
    Server x = new Server();
    x.initialize();
}

private void initialize()
{
    ServerSocket s;
    InputStream is;
    DataInputStream dis;
    while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!!
    {
        try
        {
            s = new ServerSocket(4448);
            s.setSoTimeout(0);
            s.setReuseAddress(true);
            is = s.accept().getInputStream();
            System.out.println("accepted client");
            dis = new DataInputStream(is);
            try
            {

                byte input = dis.readByte();
                System.out.println("read: " + input);
            } catch (Exception ex)
            {
                System.out.println("Exception");
                dis.close();
                is.close();
                s.close();
            }
        } catch (IOException ex)
        {
            System.out.println("ioexception");
        }
    }
}

クライアント:

public static void main(String[] args)
{
    Socket s;
    OutputStream os;
    try
    {
        s = new Socket("localhost", 4448);
        s.setKeepAlive(true);
        s.setReuseAddress(true);
        os = s.getOutputStream();
        int counter = 0;
        while (true)
        {
            try
            {
                os.write((byte) counter++);
                os.flush();

                os.close();
                s.close();

                s = new Socket("localhost", 4448);
                s.setKeepAlive(true);
                s.setReuseAddress(true);
                os = s.getOutputStream();
            } catch (Exception e)
            {
                e.printStackTrace();
                System.err.println("ERROR: reconnecting...");
            }
        }
    } catch (Exception ex)
    {
        ex.printStackTrace();
        System.err.println("ERROR: could not connect");
    }
}

誰かが正しく再接続する方法を知っていますか?

4

1 に答える 1

3

エラーが発生したときにServerSocketを閉じないでください。新しい接続を.accept()するだけです。

私が通常行うことは、ServerSocket.accept()がソケットを返すたびに、そのソケットからの送受信を処理するスレッドを生成します。そうすれば、誰かがあなたに接続したいと思ったらすぐに、新しい接続の受け入れを開始する準備が整います。

于 2009-03-23T19:34:51.610 に答える