我找到了一个处理TCP连接的类,我用它来与游戏服务进行通信。一切正常,直到我意识到如果连接速度较慢,我的应用程序停止运行。我有一个线程轮询让我们每30秒说一次。
我从这个线程Java TCP sending first message, then infinite wait
获得了我使用的TCPClient类此服务需要2个步骤来验证请求。您首先发送哈希值,然后收到并确认。然后您发送实际请求并收到回复。
public byte[] getResponse(byte[] hash, byte[] request) throws Exception{
if(client == null || client.socket.isClosed() || !client.socket.isConnected()
|| client.socket.isInputShutdown() || client.socket.isOutputShutdown(){
client = new TCPClient(this.host, this.port);
}
client.SendToServer(hash);
byte[] ack = client.ReceiveFromServer();
if(checkAck(ack, getAckForRequest(request))){
client.SendToServer(request);
byte[] response = client.ReceiveFromServer();
return response;
}
}
我的代码看起来像这样。我简化了一下以使其更具可读性。
我在try / catch块中使用此函数,当它抛出异常时,我将请求存储在MySQL数据库中。
如果连接速度很慢并且做同样的事情,有没有办法避免阻塞我的主线程?
答案 0 :(得分:1)
如果连接速度很慢并且做同样的事情,有没有办法避免阻塞我的主线程?
是。可以在Socket上调用setSoTimeout()。
Oracle文档:
https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setSoTimeout-int-
使用指定的超时启用/禁用SO_TIMEOUT,以毫秒为单位。如果将此选项设置为非零超时,则与此Socket关联的InputStream上的read()调用将仅阻止这段时间。如果超时到期,则引发java.net.SocketTimeoutException,尽管Socket仍然有效。必须在进入阻止操作之前启用该选项才能生效。超时必须> 0.超时为零被解释为无限超时。
如果您只想关闭连接并放弃它,那么效果很好。如果你想稍后恢复操作,你必须跟踪已经读取的字节,这意味着只有更多的线程通常是一个更容易的选择。