【问题标题】:Sockets- Disconnecting a client when server disconnects套接字 - 当服务器断开连接时断开客户端
【发布时间】:2017-02-22 12:44:45
【问题描述】:

我正在用 Java 编写一个带有套接字的聊天应用程序。我有这个方法,它被调用的次数与连接到服务器的客户端一样多。


public class ClientInfo implements Serializable
{
    public ObjectOutputStream writer;
    public ObjectInputStream reader;
    public String user_name;

    public ClientInfo(ObjectOutputStream writer, ObjectInputStream reader, String name)
    {
        this.reader = reader;
        this.writer = writer;
        this.user_name = name;
    }
}//end class

 /*Client side code*/
  void remove_online_user(ClientInfo client_to_remove)
        {
            try
            {
                client_to_remove.reader.close(); //this should trigger server handler in client
                client_to_remove.writer.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }//end remove_online_users()


在客户端,我创建了一个像这样的ClientInfo 对象


client = new ClientInfo(
                    new ObjectOutputStream(client_socket.getOutputStream()),
                    new ObjectInputStream(client_socket.getInputStream()),
                    user_name);

 new ServerHandler(client, this);

最后是ServerHandler(抱歉粘贴了所有代码,我正在尽力压缩它)

class ServerHandler implements Runnable
{
    private ClientInfo server;
    private ClientBackEnd client_back_end;


    public ServerHandler(ClientInfo server, ClientBackEnd client_back_end)
    {
        this.server = server;
        this.client_back_end = client_back_end;
    }//end constructor


    /*method invoked by start() call in constructor, manages communication between client and server*/
    public void run()
    {
        try
        {
            MessageInfo message;
            while ((message = (MessageInfo) server.reader.readObject()) != null)
            {
                if (message.clients != null)
                {
                    for (ClientInfo cd : message.clients)
                    {
                        if (client_back_end.listModel.contains(cd)) continue;
                        client_back_end.listModel.addElement(cd);
                    }

                    for (Object cd : client_back_end.listModel.toArray())
                    {
                        if (message.clients.contains(cd)) continue;
                        client_back_end.listModel.removeElement(cd);
                    }

                }
                else
                {
                   System.out.println("\n" + message.message_contents);
                }
            }
        }
        catch (ClassNotFoundException | IOException e)
        {
            //This should trigger during the execution of remove_online_user();
            client_back_end.disconnect_from_server(); 
        }
    }//end run()

我的目标:

当用户停止服务器时,必须断开所有客户端。在 remove_online_user() 期间,关闭 ObjectInputStream/ObjectOutputStream 应该会在客户端服务器处理程序中触发异常。但它目前没有。我做错了什么?

(如果我没有发布足够的信息,我提前道歉;我不想让任何拥有 4 个完整 .java 文件的人大吃一惊。如果需要更多信息,请告诉我)

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    关闭套接字将在对等方的readObject() 方法中触发EOFException

    出于同样的原因,您的读取循环无效。 readObject() 不会在流结束时返回 null。

    【讨论】:

    • 嗯,我知道 EOFException 是 IOException 的子类,它会触发这个异常。当您说 readObject() 在流结束时不返回 null 时,我不明白您的意思?你能解释一下吗?
    • 对我来说这似乎是一个非常清楚的陈述。哪一部分你不明白?
    • “在流的末尾”是我不明白的。为什么它不返回null?这如何回答我的问题?
    • 如果你知道流结束会触发EOFException 为什么你问我为什么它不返回null?它不返回 null (a) 因为 它抛出 EOFException 和 (b) 因为它没有说明在 Javadoc 中的流末尾返回 null。任何时候你写一个空值,它都可以返回空值。这就是 为什么 它会抛出 EOFException:需要带外值。您的代码和症状与这些方法的实际工作方式不一致。
    • 好的,我现在明白那部分了。你能提供一个解决方案吗?我看不到如何触发断开连接
    最近更新 更多