Java网络服务器和TIME_WAIT

发布于 2024-07-21 06:17:06 字数 973 浏览 1 评论 0原文

我在接收来自我公司生产的设备的信号的网络服务器方面遇到了问题。 设备偶尔会重用刚刚使用过的源端口。 这会导致 SYN 被服务器丢弃。 然后设备会重试,直到旧套接字超出服务器上的 TIME_WAIT 状态。 然后服务器发送 SYN-ACK。

服务器是用Java编写的。 不幸的是,修改设备以正确地循环端口并不是一种选择,因为现场有很多设备,并且更新现有单元也不是一种选择。 旧软件是用 C++ 编写的,并以某种方式从 Windows TCP 堆栈的列表中删除了 TIME_WAIT 端口。

任何人都可以给我提供有关如何在 Windows 上绕过 Java TIME_WAIT 的建议吗?

编辑:我确实在 Wireshark 中确认该设备正在重用最近使用过的端口。

在服务器套接字上,我使用以下选项:

socket = new ServerSocket();
socket.setPerformancePreferences(3, 2, 1);
socket.setReuseAddress(true);
socket.setSoTimeout(CLIENT_READ_TIMEOUT);
socket.bind(new InetSocketAddress(group.getPort()), MAX_TCP_BACKLOG);

客户端套接字在接收后具有以下设置:

Socket client = server.accept();
client.setKeepAlive(false);
client.setSoLinger(true, 0);
client.setReuseAddress(true);
client.setTcpNoDelay(true);
client.setSoTimeout(CLIENT_READ_TIMEOUT);

我已将 SO_LINGER 尝试为 true 和 false,具有完全相同的跟踪结果。 CLIENT_READ_TIMEOUT 设置为 10 秒。

I have run into a problem with a network server that receives signals from devices my company produces. The device will occasionally reuse the source port that it had just used. This causes the SYN to be dropped by the server. The device then retries until the old socket falls out of TIME_WAIT on the server. The server then SYN-ACKs.

The server is written in Java. Unfortunately, modifying the device to cycle ports correctly is not an option, as there are many in the field, and updating the existing units is not an option. The old software was written in C++ and somehow expunged the TIME_WAIT port from the list in the Windows TCP stack.

Can anyone offer me any advice on how to circumvent TIME_WAIT from Java on Windows?

EDIT: I have indeed confirmed in Wireshark that the device is reusing a recently used port.

On the server socket I am using the following options:

socket = new ServerSocket();
socket.setPerformancePreferences(3, 2, 1);
socket.setReuseAddress(true);
socket.setSoTimeout(CLIENT_READ_TIMEOUT);
socket.bind(new InetSocketAddress(group.getPort()), MAX_TCP_BACKLOG);

And the client socket has the following set after receiving:

Socket client = server.accept();
client.setKeepAlive(false);
client.setSoLinger(true, 0);
client.setReuseAddress(true);
client.setTcpNoDelay(true);
client.setSoTimeout(CLIENT_READ_TIMEOUT);

I have tried SO_LINGER as both true and false, with the exact same trace results. CLIENT_READ_TIMEOUT is set to 10 seconds.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眉黛浅 2024-07-28 06:17:06

基于 Nikolai 的答案,

Socket s;
...
s.setSoLinger(true,0);

Java 中的答案是等效的。

编辑:您可能想看的另一件事是 setReuseAddress(true);

Building on Nikolai's answer,

Socket s;
...
s.setSoLinger(true,0);

would be the equivalent in Java.

EDIT: Another thing you might like to look at would be setReuseAddress(true);

晨曦慕雪 2024-07-28 06:17:06

避免 TIME_WAIT不推荐老技巧是将 SO_LINGER 套接字选项设置为 { 1, 0 } - close 然后发送 RST 而不是执行正常的刷新/四向交换序列,从而避免 TIME_WAIT 一起出现(请注意 - 您可能会丢失发送缓冲区中剩余内容的尾部。)不过,我无法评论这是否可以在 Java 中完成。

编辑:您可以使用 tcpdump 确认客户端确实重用源端口号吗? 如果不是,这可能只是 Jon 指出的 SO_REUSEADDR 侦听套接字选项的经典案例。

The old not-recommended trick to avoid TIME_WAIT is to set SO_LINGER socket option to { 1, 0 } - the close then sends RST instead of doing normal flush/four-way exchange sequence, thus avoiding the TIME_WAIT all together (be warned - you might lose tail of what you still have in the send buffer.) I can't comment on whether this could be done in Java though.

EDIT: Can you confirm with tcpdump that the clients really reuse source port numbers? If not, this might just be the classic case for SO_REUSEADDR listening socket option as Jon pointed out.

柒七 2024-07-28 06:17:06

服务器忽略来自客户端的 SYN 数据包,因为它无法区分使用旧源端口的新会话的数据包和来自旧会话的重传数据包。 如果您通过设置控制块表中超时 TIME_WAIT 状态条目的系统计时器间隔来规避服务器上的 TIME_WAIT 状态,那么您的服务器将如何正确忽略已终止会话的 SYN 重传?

The server is ignoring the SYN packets from the client because it cannot distinguish between those for a new session using the old source port and retransmissions from the old session. If you circumvent the TIME_WAIT state on the server, by setting the system timer interval for aging out TIME_WAIT state entries in the control block table, then how will your server properly ignore SYN retransmissions for sessions that have already terminated?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文