代码之家  ›  专栏  ›  技术社区  ›  Hank Gay

Java网络服务器和时间等待

  •  1
  • Hank Gay  · 技术社区  · 17 年前

    我遇到了一个网络服务器问题,该服务器接收来自我公司生产的设备的信号。设备偶尔会重复使用刚刚使用的源端口。这会导致服务器删除SYN。然后,设备会重试,直到旧的套接字在服务器上的等待时间到期。然后服务器进行同步确认。

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

    有谁能给我一些建议,告诉我如何避开Windows上Java的等待时间?

    编辑:我确实在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);
    

    我试过把Sou LINGER当作真的和假的,结果完全一样。客户端读取超时设置为10秒。

    3 回复  |  直到 17 年前
        1
  •  5
  •   Jon Bright    17 年前

    基于尼古拉的回答,

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

    在Java中是等效的。

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

        2
  •  3
  •   Nikolai Fetissov    17 年前

    旧的 不推荐 避免的诀窍 TIME_WAIT 就是要设定 SO_LINGER 套接字选项 { 1, 0 } -那个 close 然后发送 RST 而不是执行正常的刷新/四路交换顺序,从而避免 等一下 总的来说(请注意,您可能会丢失发送缓冲区中仍然存在的内容。)不过,我无法评论这是否可以用Java实现。

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

        3
  •  1
  •   james woodyatt    17 年前

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

    推荐文章