- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我们遇到了一个问题,一段时间后,特定的套接字连接被阻塞,客户端的 tcp 内核不断重传 [ACK] 数据包。
拓扑流程如下:
Client A ←→ Switch A ← Router A:NAT ← .. Internet ..
→ Router B:NAT → Switch B ←→ Server B
以下是WireShark抓取的数据包:
一)服务器
1. 8013 > 6757 [PSH, ACK] Seq=56 Ack=132 Win=5840 Len=55
2. 6757 > 8013 [ACK] Seq=132 Ack=111 Win=65425 Len=0
B)客户
//lines 3 and 4 are exactly the same as line 1 and 2
3. 8013 > 13000 [PSH, ACK] Seq=56 Ack=132 Win=5840 Len=55
4. 13000 > 8013 [ACK] Seq=132 Ack=111 Win=65425 Len=0
5. 13000 > 8013 [PSH, ACK] Seq=132 Ack=111 Win=65425 Len=17
[TCP Retransmission]
6. 13000 > 8013 [PSH, ACK] Seq=132 Ack=111 Win=65425 Len=17
8013 是服务器端口,6757 是客户端 NAT 端口。
为什么TCP内核一直在发送[ACK]数据包告诉客户端它收到数据包 1(见数据包 4、5 和 6),甚至当服务器已经收到一个 [ACK] 数据包时(见数据包 2)?发生问题时,连接的任何一方都不会关闭套接字。
在第 6 个数据包之后,连接丢失了,我们无法发送任何东西到服务器不再通过该套接字。
psuedocode:
//client
serverAddr.port =htons(8013) ;
serverAddr.ip = inet_addr(publicIPB);
connect(fdA, serverAddr,...);
//server
listenfd = socket(,SO_STREAM,);
localAddr.port = htons(8013);
localAddr.ip = inet_addr(INADDR_ANY);
bind(localAddr...)
listen(listenfd, 100);
...
//using select model
select(fdSet, NULL, NULL, NULL);
for(...)
{
if (FD_ISSET(listenfd))
{
...
}
...
}
更新
UP1。下面是重现问题的具体步骤
给定三台计算机,分别是 PC1、PC2 和 PC3。 这三个都在 RouterA 后面,而 Server 在后面 路由器B。
给定两个用户 U1 和 U2。 U1 从 PC1 登录,U2 从 PC3 登录。两个都 U1 和 U2 将在它们之间建立一个 tcp 连接 和服务器。现在 U1 可以通过它发送数据 tcp 连接到服务器,然后服务器中继所有数据 到 U2。直到这一刻一切正常。
表示Server对应的socket号 U1 和 Server 之间的 TCP 连接端点: U1-OldSocketFd
不要注销U1,拔掉PC1的网线。 然后U1从PC2登录,现在建立了一个新的 到服务器的 TCP 连接。
表示Server对应的socket号 U1 和 Server 之间的 TCP 连接端点: U1-NewSocketFd
从服务器端,当它更新它的 session 时 对于 U1,它调用 close(U1-OldSocketFd)
。
4.1。在第 3 步后大约 30 秒,我们发现 U1 IS 无法通过其新的 TCP 向服务器发送任何数据 连接。
4.2。第三步,如果Server没有调用close(U1-OldSocketFd)
立即(U1 之间相同的第二个新连接 并且服务器已建立),相反,服务器调用 close(U1-OldSocketFd)
超过 70-80 秒,然后 一切正常。
UP2。路由器 B 在端口 8013 上使用端口转发。
UP3。 Server运行的Linux操作系统的一些参数。
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
最佳答案
在数据包 1(与 3 相同)和 2(与 4 相同)通过后,您的客户端似乎正在向服务器传输 17 个字节的数据(数据包 5)。我不知道在第一次交换数据包之后多长时间后数据包 5 出现,所以我不知道这种情况发生了多长时间。你的伪代码没有阐明它,因为它只显示了套接字初始化,它没有显示哪一方试图在什么时间传输什么数据。 ladder diagram在这种情况下代表您的协议(protocol)交换可能很有用。
无论如何,服务器显然不确认这 17 个字节的数据,因此再次传输它们(数据包 6)。
除非您的网络或防火墙或 NAT 路由器或其他丢弃数据包有问题,否则服务器能够接收 TCP 交换的较早部分但显然无法接收数据包的原因不应该存在5 或 6。再一次,在先前的数据交换和数据包 5 之间是否经过了大量时间(例如,NAT 路由器、防火墙或负载平衡器有足够的时间使连接过期)?
关于linux - 为什么套接字连接被阻塞,TCP 内核不断重传 [ACK] 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15192309/
使用普通的 grep 命令,有一个 --exclude 选项(详细介绍如下: Use grep --exclude/--include syntax to not grep through certa
我有 ubuntu 14.04。并使用 ack-grep 2.12 在目录内递归搜索文件中的文本 我想设置 ack-grep 选项 特定于目录 ~/workspace/project/ 这样当我在路径
我们不理解这种 TCP 行为表明 redhat linux 5 TCP 堆栈(HTTP 服务器,这是此转储的来源)收到 SYN 的 ACK,ACK 但继续忽略它并重复重复的 SYN,ACK 5次。最后
我不确定它的用途,但我正在处理的代码有一堆名为“save.d”的文件夹,看起来它们用于某种版本控制(我们也有 . svn 文件夹)。 如何更新我的 .ackrc 文件以默认忽略这些目录? 我的 .ac
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭去年。 Improve th
我已经针对运行在 Ubuntu 14.04.3 LTS (3.13.0-71-generic x86_64) 上的 OpenSSL 1.0.2e 编译了 nginx 1.9.7。我可以毫无问题地使用浏
我有添加新的 ack-grep 文件类型的语法: $ ack-grep --type-add=min=.min.js,.min.css --help types | grep min --[n
我想在任何名为 search-this-one.html 的文件中搜索字符串“my-search-string” 在我当前工作目录的所有子目录中。 我想要包含此字符串的文件的完整路径列表。有数百个名为
我正在使用 ack.pl 工具来搜索文件中的字符串或 IP ack.pl 的官方网站是 - http://beyondgrep.com/documentation/ ack.pl CLI 示例(想在/
如果您正在编写一个基本的 python TCP 服务器和客户端,您需要自己添加 SYN、SYN ACK 和 ACK 响应,还是由套接字模块处理? 如果需要自己写,会这么简单吗? 客户: #set up
[FIN, ACK]、[RST]和[RST, ACK]是什么原因,如何避免? 是否是由于 SO 的 TCP 参数之间存在某种不匹配?服务器在 TCP/IP 连接中回复 [FIN, ACK] 是什么意思
我使用 Vim 插件 ack.vim ,但我不明白为什么命令是带有大写“A”的 :Ack (按住 shift 有点烦人)。 是否可以将其重新映射到 :ack ? 最佳答案 内置命令以小写字符开头,自定
我有一个文件导致 Ack 2.0 报告“权限被拒绝”错误,所以我一直试图让它忽略该文件。 我已经在我的 ackrc 中尝试了以下内容 --type-set=lockfile:match:/NameOf
我有一个文件导致 Ack 2.0 报告“权限被拒绝”错误,所以我一直试图让它忽略该文件。 我已经在我的 ackrc 中尝试了以下内容 --type-set=lockfile:match:/NameOf
我尝试了可能的组合并在互联网上进行了搜索,但无法完成这项工作,错误是: Error: Unexpected ACK received for message-id 如果有人能指出以下代码中是否存在一些
在用 Linux C 编写的 tcp 程序中我想关闭一个 tcp 连接我使用了close(sockfd)我注意到此函数将向另一个对等方发起 FIN/ACK 数据包但是如果另一个对等点由于网络问题或 t
我已经构建了一个 c 函数,该函数应该通过 stomp 库从 ActiveMQ 读取。此代码正在读取收据之前的附加消息(这是我所期望的)。请告知为什么我的 RECEIPT 帧没有在第二个 MESSAG
我正在使用这样的 ack:ack-grep assets\\. (在 Ubuntu 上) 但是,我想排除不以“ Assets ”开头的结果。例如:网站 Assets 。 到目前为止,我已经尝试过 ac
如何使用ack搜索特定文件类型的文件。 例如 ack -f .scss blah acl -f .rb blah 显然上述方法不起作用,但是如何使用ack来做到这一点? 最佳答案 为此使用--type
每次我尝试在ack中添加类型似乎都失败了,即在ack中添加类型(log) ack --type-set log:ext:log ack: No regular expression found. 或者
我是一名优秀的程序员,十分优秀!