0

タイトルに入れるのは難しいですが、クライアントが切断されるたびに多くの例外がスローされ、サーバーは DC の後にそれ以上の接続を許可しません。ここに私が得るエラーがあります:

java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at ClientHandler.setupStreams(ClientHandler.java:34)
at ClientHandler.run(ClientHandler.java:22)

はい...クライアントがサーバーとクライアント間の接続を閉じたため、この例外が発生することを期待しています。しかし、私が理解できないのは、最初の切断後にクライアントが接続を許可しない理由です。私はそれが while ループから抜け出したと仮定していますが、なぜですか? クライアント接続を受け取り、それを受け入れ、ハンドラー クラスに渡すコードは次のとおりです。

public class ClientConnector
{
public static JTextField userText;
public static JTextArea chatWindow;
public static int Connections = 0;
public static Vector sendQueue = new Vector();
public static ArrayList<ObjectOutputStream> Streams = new ArrayList<ObjectOutputStream>();
public static Scanner input = new Scanner(System.in);


public ClientConnector()
{

}

public static void runServer()
{
    try
    {   
        System.out.println("[Info] Attempting to bind to port 1337.");
        @SuppressWarnings("resource")
        ServerSocket serversocket = new ServerSocket(1337);
        System.out.println("[Info] Bound to port 1337.");
        System.out.println("[Info] Waiting for client connections...");
        while(true)
        {
            Socket socket = serversocket.accept();
            new ClientHandler(socket).start();
            Connections += 1;


        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
}

それはかなり簡単です。クライアント接続を処理するコードについては、次のとおりです。

public class ClientHandler extends Thread
{
Socket ConnectedClient;
static ObjectOutputStream Output;
static ObjectInputStream Input;
public static boolean isError = false;
public static int updateCounter = 0;

ClientHandler(Socket socket)
{
    ConnectedClient = socket;
}

public void run()
{

    while(true)
    {
        setupStreams();//22
        WhileChatting();
    }
}

public void setupStreams()
{
    try 
    {
        if(isError == false)
        {
            Output = new ObjectOutputStream(ConnectedClient.getOutputStream());
            Input = new ObjectInputStream(ConnectedClient.getInputStream());//34
            ClientConnector.Streams.add(Output);
        }   
    }
    catch (IOException e)
    {
        isError = true;
        e.printStackTrace();
    }

}


public static void WhileChatting()
{
    String Message = "";
    do
    {
        try
        {
            if(isError == false)
            {
                Message = (String)Input.readObject();
                for(int i = 0; i < ClientConnector.Streams.size(); i++)
                {
                    ClientConnector.Streams.get(i).writeObject(Message);
                    System.out.println(Message);
                }
            }

        }
        catch(ClassNotFoundException CNFE)
        {
            isError = true;
            CNFE.printStackTrace();
        }
        catch(EOFException eof)
        {
            for(int i = 0; i < ClientConnector.Streams.size(); i++)
            {
                try
                {
                    Output.close();
                    Input.close();
                    ClientConnector.Streams.get(i).close();
                    ClientConnector.Streams.remove(i);
                    System.out.println("Connection lost");
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }

            }
        }
        catch (IOException e)
        {
            isError = true;
            e.printStackTrace();
        }

    }
    while(Message != "/disconnect");
}

public static void sendMessage(String message)
{
    try
    {
        if(isError == false)
        {
            Output.writeObject(message);
            System.out.println(message);
        }
    }
    catch(IOException Ex)
    {
        isError = true;
        Ex.printStackTrace();
    }
}

public static void sendServerMessage(String message)
{
    int Limit = 0;
    try
    {
        for(int i = 0; i < ClientConnector.Streams.size(); i++)
        {
            if(Limit == 0)
            {
                ClientConnector.Streams.get(i).writeObject("\247c[Server] \247d" + message);
                System.out.println("\247c[Server] \247d" + message);
                Limit = 1;
            }
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

public static void closeConnections()
{
    try
    {
        if(isError == false)
        {
            Output.close();
            Input.close();
            //ConnectedClient.close();
        }
    }
    catch(IOException Ex)
    {
        isError = true;
        Ex.printStackTrace();
    }
}

}

影響を受けた行にコメントしました。エラーは、クライアントが切断された後に発生します。それがwhileループを壊す原因となる例外なのか、それとも別のものなのかはわかりません。クライアントが切断された後、このコードを継続して着信接続を許可するにはどうすればよいですか。System.out.println のデバッグと使用を試みました。回答してくれたすべての人に事前に感謝します。

4

1 に答える 1

0

はい...クライアントがサーバーとクライアント間の接続を閉じたため、この例外が発生することを期待しています。

いいえ。この例外は、閉じてSocketからさらに I/O を実行しようとしたことを意味します。ピアとは何の関係もありません。

しかし、私が理解できないのは、最初の切断後にクライアントが接続を許可しない理由です。

コードには多くの問題があります。

  1. の存続期間中、両端で同じObjectInputStreamとを使用する必要があります。現在、ループのたびに新しいペアを作成し、それらをデータ構造に追加しています。ObjectOutputStreamSocket

  2. EOFException1 つをキャッチすると、すべてのソケットSocketが閉じられます。例外を取得した 1だけを閉じてから、すべてのループから抜け出し、スレッドを終了できるようにする必要があります

  3. 基本的に、whileループを からwhile (true)に変更し、他の場所でのwhile (!isError)テストを停止する必要がありisErrorます。メソッドを削除whileChattingして、この while ループに組み込みます。doそして、内側のループは必要ありません。EOS または切断コマンドまで読み取るループが 1 つだけ必要です。

于 2013-04-23T00:01:47.297 に答える