gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:33:24 24 4
gpt4 key购买 nike

如何防止 TCP 进行多次套接字连接尝试?

背景

我正在尝试粗略估计到客户的往返时间。我必须使用的高级协议(protocol)无法确定 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 的调用在放弃之前进行了三次(失败)连接套接字尝试 - 尝试间隔显然是任意的(通常约为 300 毫秒)。

Me -> Client: SYN
Client -> Me: ACK, RST
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.
*/

...但遗憾的是,没有证据表明该函数或我看过的任何其他(非 native )函数中有循环/重试。

这种重试行为实际上从何而来?又如何控制?

备选方案

我也可能对其他选择持开放态度,但不是...

  • 使用 ICMP 回应请求(ping)。我知道很多客户不会回复他们。
  • 使用原始套接字。其中一个平台是 Windows,如今它严重限制了使用原始套接字的能力。 (我还认为,如果 Linux 网络堆栈陷入试图使用原始套接字执行 TCP 的应用程序的交火中,它就会毫无帮助地跳入。)
  • 除非万不得已,否则使用 JNI。我的代码需要在至少 2 个截然不同的操作系统上运行。

最佳答案

TCP 连接重试是操作系统套接字实现的一个功能。配置这取决于平台。参见 https://security.stackexchange.com/questions/34607/why-is-the-server-returning-3-syn-ack-packets-during-a-syn-scan了解这是什么以及为什么会发生。

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

与 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.

顺便说一句,re: raw sockets - 是的,你会遇到非常困难的时期。此外,从 Windows XP SP2 开始,Windows won't actually let you specify TCP protocol numbers for raw sockets under any circumstances (请参阅限制)。

此外,顺便说一句:确保 TCP 连接没有被客户端前面的单独防火墙阻止,否则您最终只能测量到防火墙的往返时间。

关于java - 防止 TCP 套接字连接重试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22417228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com