2010-12-03 80 views
0

我已经为Android手机创建了一个MMO,并使用带有TCP/IP套接字的Java服务器。一切正常,一切正常,但大约一天的客户端登录和离开我的网络变得非常滞后 - 即使没有连接客户端。 NETSTAT没有显示任何连接,但显然有一些可怕的错误发生。Java TCP/IP服务器关闭连接不正确

如果我重新启动一切,神奇的一切都会好起来,但这不是一个长期成功的解决方案。这是我的脱节方法看起来像(两端):

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实现中看起来严重的隐藏缺陷感到沮丧。

+0

我应该补充说,2分钟没有活动后,所有的客户端都会断开连接。从静默断开连接的客户端锁定receive()线程没有问题。 – jysend 2010-12-03 19:30:35

回答

2

摆脱shutdownInput()和shutdownOutput()以及除BufferedOutputStream的close之外的所有闭包,并且随后在一个finally块中关闭套接字本身作为带子&大括号。您正在关闭并关闭其他所有之前的输出流,从而防止其冲洗。关闭输出流会刷新它并关闭套接字。这就是你需要的。

0

OP在这里,无法对原帖发表评论。

  • 重新启动服务器进程似乎不能解决问题。在完全关闭服务器后的几分钟内,网络仍然很“滞后”。

  • “laggy”我的意思是连接变得非常缓慢,无论上行和下行流量。试图加载网站,或上传到我的FTP,是痛苦的缓慢,就像我在一个14.4k调制解调器(我在15mbs光纤)。互联网速度测试在它处于这种状态时甚至不起作用 - 当网站最终加载时,我得到一个关于找不到文件的错误。

  • 所有这些在重新启动后立即清除,并且仅在重新启动后立即清除。

  • 我修改了EJP建议的断开方法,但问题仍然存在。

  • 服务器运行在Windows 7安装上,最新版本的Java/Java SDK。服务器有16GB的内存,尽管可能我没有正确分配给JVM充分使用。似乎不存在任何流浪线程或进程。我会看看JVISUALVM说什么。 - jysend 13分钟前

  • JVISUALVM中没有什么不寻常 - 10MB堆,CPU使用率50%,3160个对象(预计),437个活动线程中有27个启动。服务器已运行约18小时;加载CNN的首页大约需要一分钟,而我使用的正常速度测试(首次打谷歌速度测试)甚至不会加载页面。 NETSTAT显示没有任何连接。随时更新防病毒软件。服务器在过去24/7运行,没有任何问题 - 只有当我开始运行这个Java服务器时,才会发生这种情况。