套接字停止发送消息但不会超时

时间:2015-08-12 07:22:51

标签: java android sockets

问题:

我制作了具有即时消息功能的应用。在大多数情况下,发送和接收消息没有任何问题。但是在一段时间之后,大约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

问题

究竟是什么问题或者我怎么能进一步调试呢?

3 个答案:

答案 0 :(得分:3)

记录你所做的事是徒劳的。什么也没发生。

如果连接已经死亡,发送迟早会导致IOException: connection reset.但不是第一次,因为套接字缓冲。

当你得到这个例外时,不要只返回false。关闭连接。

HOWEVER 这里的问题是PrintWriter.它吞下了异常。见Javadoc。调用checkError(),它返回一个布尔值,指示是否存在异常,或者更好的是,根本不使用PrintWriter:使用BufferedWriter.write().newLine(),和.flush(),所有这些都可以抛出IOExceptions。这样更好,因为您可以看到实际上的异常。当然,在目前误导性的日志消息之前,您必须将所有内容移到try块中。

不要对每条消息使用新的PrintWriterBufferedWriter。在插座的使用寿命中使用相同的插座。

答案 1 :(得分:1)

在发送任何消息之前,您必须检查连接是否仍然存在b / w客户端和服务器。

如果网络连接变慢或介于两者之间关闭,则连接可能会中断,或者有时它会从服务器端变为死连接,因为两者都没有通信。

你可以尝试两件事:

<强> 1 制作一个发送消息检查的通用方法 if:连接存在然后只发送消息 else:首先建立连接并发送该消息。

我们在Websockets中遇到了同样的问题并使用了相同的startegy。

<强> 2 要求服务器端团队继续从他们那边发送一些心跳包,这样你的连接就不会死了。

对我们来说,第一个策略已经制定出来并且更好。

试一试。 :)

答案 2 :(得分:0)

我认为问题不一定在于客户端设备或服务器,而在于我的NAT路由器之间的问题。由于不活动,路由器很可能会丢弃其表中的映射。

我的解决方案是使用心跳功能(以及修改我使用PrintWriter作为EJP建议),每隔45秒从客户端发送到服务器。我很可能将时间随机化,只是为了处理大量人同时登录并影响服务器性能的情况。

相关问题