我有一个客户端应用程序和一个服务器应用程序。客户端应用程序通过java.net.Socket(Protocol = TCP)将数据包发送到服务器应用程序。在Socket.Close()上,我的服务器应用程序立即向我显示连接已关闭 - 这就是它必须正常工作的方式。注意:整个tcp-streaming逻辑处于辅助活动中,这就是我使用onBackPressed()函数完成整个tcp-streaming并切换到主要活动的原因。
工作方案:
@Override
public void onBackPressed(){
m_socket.Close();
finish();
}
如上所述,套接字关闭,服务器立即通知连接已关闭。
不工作的场景,因为Socket.close()似乎太慢了:
@Override
public void onBackPressed(){
m_socket.Close();
m_wifiManager.disconnect();
finish();
}
此方案仅在20%的情况下正常运行。在另外80%我的服务器应用程序通过大延迟通知连接已关闭。在我看来,这是因为tcp-socket需要关闭的时间 - 因此进程被wifi连接断开而中断,并且无法正确关闭套接字(#)。作为我的观点的证明:如果我逐步调试它,这种情况在100%的情况下有效。服务器立即通知。
我已经尝试了什么,哪些也无法正常工作:
m_wifiManager.disconnect()
中 onPause()
在m_wifiManager.disconnect()
onDestroy()
所以我的问题是:
我的意见(#)是否正确?是否缺少套接字关闭时间?
我该如何解决这个问题?这样tcp-socket-closing能够正常完成,就像在第一个场景中一样,然后wifi断开连接?
答案 0 :(得分:2)
问题可能出在SO_LINGER套接字选项:
指定延迟关闭超时。此选项禁用/启用从TCP套接字的close()立即返回。 使用非零整数超时启用此选项意味着close()将阻止传输并确认写入对等方的所有数据,此时套接字正常关闭。达到延迟超时后,使用TCP RST强制关闭套接字。启用超时为零的选项会立即强制关闭。如果指定的超时值超过65,535,则将减少到65,535。
默认情况下已禁用,您的close
调用会立即返回,并在套接字实际关闭之前断开wifi连接。您需要致电setSoLinger进行修复:
m_socket.setSoLinger(true, 1);