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. 您必须在两端使用相同的ObjectInputStreamandObjectOutputStream在 , 的生命周期内。Socket目前,您正在创建一个新对,并将它们添加到数据结构中,每次循环。

  2. 当你抓住EOFException一个Socket时,你正在关闭所有的套接字。您应该只关闭一个,即您从中获得异常的那个,然后您必须跳出所有循环并允许线程退出。

  3. 您基本上应该将while循环从while (true)to更改为while (!isError)并停止isError在其他任何地方进行测试。我将摆脱该whileChatting方法并将其合并到此 while 循环中。而且你不需要内do循环。您只需要一个循环读取直到 EOS 或断开命令。

于 2013-04-23T00:01:47.297 回答