问题:
我制作了具有即时消息功能的应用。在大多数情况下,发送和接收消息没有任何问题。但是在一段时间之后,大约10到40分钟之间,如果客户端的套接字暂时没有使用,则消息不再到达服务器。例如,如果我与某人聊天,请打开应用程序,小睡一会儿,然后再回来聊天,然后消息就不会发送。我99%肯定这不是服务器端的问题,因为我打印出收到的所有内容(而且它没有收到任何东西),如果我用另一部手机登录,它可以正常工作。
我尝试过的事情:
起初我认为这是客户端的超时问题,因为在服务器端我不断收到错误说,"连接由peer"重置,在某个地方,在10-40分钟内。我(几乎)通过使用Java.net.socket
的{{1}}方法解决了这个问题,超时值为0,这给出了无限超时:
connect()
我很少得到#34;连接由同行重置"现在出现错误信息,但是在一段时间后发送的消息的神秘问题仍然存在。
代码:
这是我的clientSocket = new Socket();
clientSocket.connect( new InetSocketAddress(ServerInfo.IP, ServerInfo.PORT_NUMBER), 0 );
功能,它始终记录" SOCKET OPERATOR SENDING MESSAGE:' message'":
sendMessage
问题:
究竟是什么问题或者我怎么能进一步调试呢?
答案 0 :(得分:3)
记录你所做的事是徒劳的。什么也没发生。
如果连接已经死亡,发送迟早会导致IOException: connection reset.
但不是第一次,因为套接字缓冲。
当你得到这个例外时,不要只返回false。关闭连接。
HOWEVER 这里的问题是PrintWriter.
它吞下了异常。见Javadoc。调用checkError()
,它返回一个布尔值,指示是否存在异常,或者更好的是,根本不使用PrintWriter
:使用BufferedWriter.write()
和.newLine()
,和.flush()
,所有这些都可以抛出IOExceptions
。这样更好,因为您可以看到实际上的异常。当然,在目前误导性的日志消息之前,您必须将所有内容移到try
块中。
不要对每条消息使用新的PrintWriter
或BufferedWriter
。在插座的使用寿命中使用相同的插座。
答案 1 :(得分:1)
在发送任何消息之前,您必须检查连接是否仍然存在b / w客户端和服务器。
如果网络连接变慢或介于两者之间关闭,则连接可能会中断,或者有时它会从服务器端变为死连接,因为两者都没有通信。
你可以尝试两件事:
<强> 1 强> 制作一个发送消息检查的通用方法 if:连接存在然后只发送消息 else:首先建立连接并发送该消息。
我们在Websockets中遇到了同样的问题并使用了相同的startegy。
<强> 2 强> 要求服务器端团队继续从他们那边发送一些心跳包,这样你的连接就不会死了。
对我们来说,第一个策略已经制定出来并且更好。
试一试。 :)
答案 2 :(得分:0)
我认为问题不一定在于客户端设备或服务器,而在于我的NAT路由器之间的问题。由于不活动,路由器很可能会丢弃其表中的映射。
我的解决方案是使用心跳功能(以及修改我使用PrintWriter作为EJP建议),每隔45秒从客户端发送到服务器。我很可能将时间随机化,只是为了处理大量人同时登录并影响服务器性能的情况。