我有一个客户端应用程序和服务器应用程序。客户端应用程序通过java.net.socket(协议= TCP)将数据包发送到服务器应用。在socket.close()我的服务器应用程序上立即向我展示了该连接已关闭 - 这就是必须正常工作的方式。注意:整个TCP流逻辑都处于辅助活动中,这就是为什么我使用onbackpressed()函数来完成整个TCP流并切换到主要活动。
工作场景:
@Override
public void onBackPressed(){
m_socket.Close();
finish();
}
正如解释的插座被关闭的那样,服务器立即通知连接是否已关闭。
无法工作的情况,因为socket.close()似乎太慢了:
@Override
public void onBackPressed(){
m_socket.Close();
m_wifiManager.disconnect();
finish();
}
这种情况仅在20%的情况下才能正常工作。在其他80%的我的服务器应用中,我通知连接使用大延迟关闭。我认为这是因为TCP插座需要结束的时间 - 因此该过程被WiFi连接断开连接所中断,并且无法适当关闭插座(#)。作为我认为的证明:如果我逐步调试,这种情况在100%的情况下起作用。服务器立即通知。
我已经尝试过的东西,什么也无法正常工作:
m_wifiManager.disconnect()
inonPause()
m_wifiManager.disconnect()
inonDestroy()
所以我的问题是:
我的意见(#)正确吗?插座是否缺乏时间?
我该如何解决?因此,TCP-socket关闭效果正确,例如在第一种情况下,然后wifi断开连接?
问题可能与so_linger套接字选项:
指定挂钩暂停超时。此选项禁用/启用TCP套接字的CLOSS()立即返回。使用非零整数超时启用此选项意味着CLOSS()将阻止(),等待将所有数据写入对等方的传输和确认,此时,该插座是优雅地关闭的。到达流连忘返的超时后,插座用TCP RST强行闭合。以零超时的启用选项会立即有效关闭。如果指定的超时值超过65,535,则将减少到65,535。
默认情况下是禁用的,您的close
呼叫立即返回,并且在插座实际关闭之前断开WiFi。您需要致电SetSolinger进行修复:
m_socket.setSoLinger(true, 1);