Java - 奇怪的挂插座?

5 java sockets

我有一个带有java服务器的客户端 - 服务器应用程序.它的工作非常完美,只是经过一段时间后,突然间,一个插座一直悬挂着.这个套接字只是其中之一,其余的似乎仍然很好,但一旦进入套接字,服务器就不会超过发送线.这些是代码的相关部分:

Socket socket; // A normal socket
out  = new PrintWriter(socket.getOutputStream(), true); // The outstream
out.println(msg + "\0"); // This command is used to send stuff, msg is a String
Run Code Online (Sandbox Code Playgroud)

没有抛出任何异常,行应用程序似乎没有超出该行:

out.println(msg + "\0");
Run Code Online (Sandbox Code Playgroud)

我知道String是一个很好的,导致4或5个其他套接字之前,这个可以发送它就好了.另请注意,据我所知,这个套接字可以在突然挂起之前发送数百条消息.有谁知道我应该寻找什么样的错误?

jpd*_*gle 5

有很多事情可能导致这种情况,但听起来你可能在TCP级别上得到了反压.

通常,当您在套接字上发送数据时,它只是缓冲而且发送调用(在您的情况下,println()flush())可以在数据实际发送到网络之前返回.可能是您在此套接字上的所有先前写入都被缓冲到本地SO_SNDBUF,您只需填写它.

(1)你能用tcpdump或Wireshark来追踪它,并找到挂起的确切连接(我知道这很难连接很多)?在程序挂起时检查TCP窗口大小将告诉您更多关于是在Java本身还是在网络级别阻止.

(2)倾倒堆叠并将其贴在这里.Java套接字有一个内部锁,可以防止两个线程同时写入它们.您确定在您尝试写入时,只有一个线程正在访问该套接字吗?

你肯定想尝试做一个

$ jstack <PID>
Run Code Online (Sandbox Code Playgroud)

当它被冻结以确切地看到它挂在哪里,以及如果写线程试图获得任何锁定.