加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 防止TCP套接字连接重试

发布时间:2020-12-15 04:18:38 所属栏目:Java 来源:网络整理
导读:如何防止TCP进行多个套接字连接尝试? 背景 我试图粗略估计一下客户的往返时间.我必须使用的高级协议无法确定RTT,也没有任何类型的无操作请求/响应流程.所以,我试图直接从较低层获取信息.特别是,我知道客户端将主动拒绝特定端口上的TCP连接尝试. Me - Client
如何防止TCP进行多个套接字连接尝试?

背景

我试图粗略估计一下客户的往返时间.我必须使用的高级协议无法确定RTT,也没有任何类型的无操作请求/响应流程.所以,我试图直接从较低层获取信息.特别是,我知道客户端将主动拒绝特定端口上的TCP连接尝试.

Me -> Client: SYN
Client -> Me: ACK,RST

long lStartTime = System.nanoTime() / 1000000;
  long lEndTime;

  // Attempt to connect to the remote party.  We don't mind whether this
  // succeeds or fails.
  try
  {
    // Connect to the remote system.
    lSocket.connect(mTarget,MAX_PING_TIME_MS);

    // Record the end time.
    lEndTime = System.nanoTime() / 1000000;

    // Close the socket.
    lSocket.close();
  }
  catch (SocketTimeoutException|IOException lEx)
  {
    lEndTime = System.nanoTime() / 1000000;
  }

  // Calculate the interval.
  lInterval = lEndTime - lStartTime;
  System.out.println("Interval = " + lInterval);

问题

使用Wireshark,我看到对lSocket.connect的调用使得三次(失败)尝试在放弃之前连接套接字 – 显然是任意的尝试间间隔(通常为~300ms).

Me -> Client: SYN
Client -> Me: ACK,RST
Me -> Client: SYN
Client -> Me: ACK,RST

有没有办法让TCP在单个SYN / RST对之后放弃?

我查看了一些Java代码.当AbstractPlainSocketImpl上的评论说…时,我想知道我是不是赢了.

/**
 * The workhorse of the connection operation.  Tries several times to
 * establish a connection to the given <host,port>.  If unsuccessful,* throws an IOException indicating what went wrong.
 */

…但遗憾的是,没有证据表明该函数或我所看到的任何其他(非本机)函数存在循环/重试.

这种重试行为实际上来自哪里?它怎么能被控制?

备择方案

我也可以接受替代方案,但不是……

>使用ICMP回应请求(ping).我知道许多客户不会回复他们.
>使用原始套接字.其中一个平台是Windows,这些天严重限制了使用原始套接字的能力. (我还认为,如果Linux网络堆栈遇到了试图使用原始套接字来执行TCP的应用程序的交叉攻击,那么Linux网络堆栈就无济于事.)
>使用JNI,除非作为最后的手段.我的代码需要在至少2个非常不同的操作系统上工作.

解决方法

TCP连接重试是OS的套接字实现的一个功能.配置这取决于平台.有关这是什么以及为什么会发生这种情况的说明,请参见 https://security.stackexchange.com/questions/34607/why-is-the-server-returning-3-syn-ack-packets-during-a-syn-scan.

在Windows上,您应该能够修改注册表中的重试次数:

> HKLMSYSTEMCurrentControlSetServicesTcpipParametersTcpMaxConnectRetransmissions

与RTT相关的设置也在该文档中详细说明.

在Linux上,链接的安全帖子中接受的答案讨论了如何配置此参数:

On a Linux system,see the special files in /proc/sys/net/ipv4/ called tcp_syn_retries and tcp_synack_retries: they contain the number of times the kernel would emit SYN (respectively SYN+ACK) on a given connection … this is as simple as echo 3 > tcp_synack_retries

请注意,这是一个系统范围的设置.

您可以通过读取注册表设置(在Windows上)或读取特殊文件的内容(在Linux上)来读取当前值.

此外,MSDN有关于Windows上TCP连接RTT的说法:

TCP/IP adjusts the frequency of retransmissions over time. The delay between the original transmission and the first retransmission for each interface is determined by the value of the TcpInitialRTT entry. By default,it is three seconds. This delay doubles after each attempt. After the final attempt,TCP/IP waits for an interval equal to double the last delay,and then it abandons the connection request.

顺便说一句,重新:原始套接字 – 是的,你将有一个非常困难的时间.此外,从Windows XP SP2,Windows won’t actually let you specify TCP protocol numbers for raw sockets under any circumstances开始(请参阅限制).

另外,请注意:确保TCP连接没有被客户端前面的单独防火墙阻止,否则您最终只能测量到防火墙的往返时间.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读