Socket read()和ready()互锁,客户端断开连接检测

发布于 2025-01-01 07:56:13 字数 2509 浏览 2 评论 0原文

好吧,我的问题很简单。我正在尝试进行简单的聊天,但我认为检测与服务器断开连接的客户端是强制性的。当我使用简单时,聊天工作正常(没有这样的检测):

                if (this.in.ready())  //preinitialized buffered reader
                    this.dataIn=this.in.readLine();

我浏览了这里发布的很多网站/问题,我读到应该忽略 ready() ,因为它会阻止一切,这可能是真的,因为当我删除此 ready() 时,我的聊天不再有效,但它启用了客户端断开连接检测。

为了达到我的目标,我需要测试 BufferedReader 是否通过 readLine() 接收 null,但这也不起作用。

            if (this.in.readLine()!=null){ //1. check if client disconnected
                if (this.in.ready())       //2/
                    this.dataIn=this.in.readLine(); //3.
            }                    
            else
                this.notice="Client disconnected!";

现在,当我应用上面提供的代码时会发生什么。初始 if (1) 正在阻塞内部 ready()(第 2 行),这是读取通过套接字 (3) 发送的实际消息所必需的。

另一种“命令”不起作用:

            if (this.in.ready()){
                this.dataIn=this.in.readLine();
            }
            else if (this.in.readLine()!=null)
                this.notice="Client disconnected!";

该命令也不允许通过套接字发送消息。

*是的,发送/接收是在单独的线程中实现的

*BufferedReader 仅初始化一次

线程源代码(如果有任何1需要它才能查看):

    @Override
public void run() {
    try {
        if (this.isServer){            
            this.initServer();
            this.initProcessData(sSocket);
        } 
        else if (!this.isServer){
            this.initClient();
            this.initProcessData(clientSocket);
        }            
        this.initDone=true;

    } catch (IOException ex) {
        Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
    }

    while(this.initDone){
        try {
            Thread.sleep(100);
            if ((!this.dataOut.isEmpty())&&(this.dataOut!="")){                
                this.out.println(this.dataOut);
                this.out.flush();
                this.dataOut = "";
            }
            if (this.in.ready())
                this.dataIn=this.in.readLine();                   
        }
        catch (IOException ex) {
            Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (InterruptedException ex) {  
            this.initDone=false;
                Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }

        //System.out.println(this.notice);
    }

}

最糟糕的是我要么正确检测到客户端断开连接,要么我有工作聊天。

谁能告诉我我应该做什么才能将这两者结合在一起?非常感谢任何帮助。

Ok my issue is simple. I am trying to make simple chat but i feel that detection of disconnected client from server is mandatory. Chat works fine (without such detection) when i use simple:

                if (this.in.ready())  //preinitialized buffered reader
                    this.dataIn=this.in.readLine();

I have browsed lots of websites/questions posted here and i read that ready() should be ommited since it blocks everything, that may be true since when i delete this ready() my chat no longer works, however it enables client disconnected detection.

In order to reach my goal i need to test if BufferedReader recieves null through readLine() but this does not work as it should either.

            if (this.in.readLine()!=null){ //1. check if client disconnected
                if (this.in.ready())       //2/
                    this.dataIn=this.in.readLine(); //3.
            }                    
            else
                this.notice="Client disconnected!";

Now what happens when i apply code presented above. Initial if (1) is blocking the inner ready() (line 2) which is required to read actual message send over socket (3).

The other "order" does not work:

            if (this.in.ready()){
                this.dataIn=this.in.readLine();
            }
            else if (this.in.readLine()!=null)
                this.notice="Client disconnected!";

This one also does not allow to send messages through socket.

*Yes, sending/recieving is realized in separate thread

*BufferedReader is initialized only once

Thread source code (if any1 would need it in order to take a look):

    @Override
public void run() {
    try {
        if (this.isServer){            
            this.initServer();
            this.initProcessData(sSocket);
        } 
        else if (!this.isServer){
            this.initClient();
            this.initProcessData(clientSocket);
        }            
        this.initDone=true;

    } catch (IOException ex) {
        Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
    }

    while(this.initDone){
        try {
            Thread.sleep(100);
            if ((!this.dataOut.isEmpty())&&(this.dataOut!="")){                
                this.out.println(this.dataOut);
                this.out.flush();
                this.dataOut = "";
            }
            if (this.in.ready())
                this.dataIn=this.in.readLine();                   
        }
        catch (IOException ex) {
            Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (InterruptedException ex) {  
            this.initDone=false;
                Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
        }

        //System.out.println(this.notice);
    }

}

The worst thing is that i have either proper detection of client disconnected or i have working chat.

Can anyone enlight me what should i do in order to combine those two together? Any help greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小伙你站住 2025-01-08 07:56:13

考虑使用 java.io.ObjectInputStream 和 java.io.ObjectOutputStream。在单独的工作线程中使用阻塞 read() 方法,并循环直到它返回 -1 或引发异常。来回发送 String 对象。这样,您还可以发送带有换行符的消息。

Consider using java.io.ObjectInputStream and java.io.ObjectOutputStream. Use the blocking read() method in a separate worker thread, and loop until it returns -1 or throws an exception. Send String objects back and forth. In that way, you can also send messages with line feeds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文