我为 Android 手机创建了一个 MMO,并使用带有 TCP/IP 套接字的 Java 服务器。一般来说,一切都工作正常,但在客户端登录和注销大约一天之后,我的网络变得非常滞后——即使没有客户端连接。 NETSTAT 显示没有延迟连接,但显然出现了严重错误。
如果我完全重新启动,一切都会奇迹般地再次正常,但这不是长期可行的解决方案。这就是我的断开连接方法的样子(两端):
public final void disconnect()
{
Alive = false;
Log.write("Disconnecting " + _socket.getRemoteSocketAddress());
try
{
_socket.shutdownInput();
}
catch (final Exception e)
{
Log.write(e);
}
try
{
_socket.shutdownOutput();
}
catch (final Exception e)
{
Log.write(e);
}
try
{
_input.close();
}
catch (final Exception e)
{
Log.write(e);
}
try
{
_output.close();
}
catch (final Exception e)
{
Log.write(e);
}
try
{
_socket.close();
}
catch (final Exception e)
{
Log.write(e);
}
}
_input 和 _output 是从套接字生成的 BufferedInputStream 和 BufferedOutputStream。根据文档,调用 shutdownInput() 和 shutdownOutput() 不是必要的,但我会尽我所能。
我使用默认设置实例化套接字——我没有接触 soLinger、KeepAlive、noDelay 或类似的东西。我没有为发送/接收设置任何超时。我尝试过使用 WireShark,但它没有显示任何异常,就像 NETSTAT 一样。
我非常渴望得到这个问题的答案。我在这个项目上投入了大量的精力,但对 Java 默认 TCP 实现中似乎存在的严重隐藏缺陷感到沮丧。
最佳答案
摆脱 shutdownInput() 和 shutdownOutput() 以及除 BufferedOutputStream 的关闭之外的所有关闭,以及在 finally block 中作为带和大括号对套接字本身进行后续关闭。您将关闭并关闭输出流之前的所有其他内容,这会阻止其刷新。关闭输出流会刷新它并关闭套接字。这就是您所需要的。
关于Java TCP/IP 服务器不正确地关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4349009/