And*_*ose 4 java language-agnostic sockets tcp
如何防止TCP进行多个套接字连接尝试?
我试图粗略估计一下客户的往返时间.我必须使用的高级协议无法确定RTT,也没有任何类型的无操作请求/响应流程.所以,我试图直接从较低层获取信息.特别是,我知道客户端将主动拒绝特定端口上的TCP连接尝试.
Me -> Client: SYN
Client -> Me: ACK, RST
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
使用Wireshark,我看到lSocket.connect在放弃之前调用三次(失败)尝试连接套接字 - 显然是任意的尝试间间隔(通常约为300ms).
Me -> Client: SYN
Client -> Me: ACK, RST
Me -> Client: SYN
Client -> Me: ACK, RST
Me -> Client: SYN
Client -> Me: ACK, RST
Run Code Online (Sandbox Code Playgroud)
有没有办法让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.
*/
Run Code Online (Sandbox Code Playgroud)
...但遗憾的是,没有证据表明该函数或我所看到的任何其他(非本机)函数存在循环/重试.
这种重试行为实际上来自哪里?它怎么能被控制?
我也可以接受替代方案,但不是......
TCP连接重试是OS的套接字实现的一个功能.配置这取决于平台.请参阅https://security.stackexchange.com/questions/34607/why-is-the-server-returning-3-syn-ack-packets-during-a-syn-scan,了解这是什么以及为什么正在发生.
在Windows上,您应该能够修改注册表中的重试次数:
与RTT相关的设置也在该文档中详细说明.
在Linux上,链接的安全帖子中接受的答案讨论了如何配置此参数:
在Linux系统上,看到特殊的文件
/proc/sys/net/ipv4/名为tcp_syn_retries和tcp_synack_retries:它们包含的次数内核将一个给定的连接上发出SYN(分别为SYN + ACK)......这就是这么简单echo 3 > tcp_synack_retries...
请注意,这是一个系统范围的设置.
您可以通过读取注册表设置(在Windows上)或读取特殊文件的内容(在Linux上)来读取当前值.
此外,MSDN有关于Windows上TCP连接RTT的说法:
TCP/IP随时间调整重传频率.每个接口的原始传输和第一次重传之间的延迟由
TcpInitialRTT条目的值确定.默认情况下,它是三秒钟.每次尝试后,此延迟加倍.在最后一次尝试之后,TCP/IP等待的间隔等于上一次延迟的两倍,然后它放弃连接请求.
顺便说一句,重新:原始套接字 - 是的,你将有一个非常困难的时间.此外,从Windows XP SP2开始,Windows 实际上不允许您在任何情况下为原始套接字指定TCP协议号(请参阅限制).
另外,请注意:确保TCP连接没有被客户端前面的单独防火墙阻止,否则您最终只能测量到防火墙的往返时间.