我最近一直在研究一些服务器客户端代码,我发现这是一个非常令人困惑的问题。我有一个server
监听端口并设置 backlog = 2 ,以及我的客户端创建5个帖子到connect
。
在man
中,我注意到了
The backlog parameter defines the maximum length for the queue of pending connections. If a connection request arrives with the queue full, the client may receive an error with an indication of ECONNREFUSED. Alterna- tively, if the underlying protocol supports retransmission, the request may be ignored so that retries may succeed.
这意味着我的客户端连接将失败或稍后重试。
但是当我的客户端运行时,它只是收到一个SIGPIPE信号并失败。
所以我运行sudo tcpdump -ilo0 port 10000
并得到结果:
summertekiMacBook-Pro:选择夏天$ sudo tcpdump -ilo0端口10000
tcpdump:详细输出被抑制,使用-v或-vv对lo0进行全协议解码侦听,链接类型为NULL(BSD环回),捕获大小为65535字节
10:29:16.396240 IP localhost.56347> localhost.ndmp:Flags [S],seq 3366561899,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 0,sackOK,eol],length 0
10:29:16.396241 IP localhost.56349> localhost.ndmp:Flags [S],seq 902832276,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 0,sackOK,eol],length 0
10:29:16.396242 IP localhost.56351> localhost.ndmp:Flags [S],seq 1956535575,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 0,sackOK,eol],length 0
10:29:16.396244 IP localhost.56348> localhost.ndmp:Flags [S],seq 2161003109,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 0,sackOK,eol],length 0
10:29:16.396246 IP localhost.56350> localhost.ndmp:Flags [S],seq 1318035540,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 0,sackOK,eol],length 0
10:29:16.396296 IP localhost.ndmp> localhost.56347:Flags [S.],seq 2871094527,ack 3366561900,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 396158772,sackOK,eol],length 0
10:29:16.396307 IP localhost.ndmp> localhost.56351:Flags [S.],seq 3931313020,ack 1956535576,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 396158772,sackOK,eol],length 0
10:29:16.396332 IP localhost.ndmp> localhost.56349:Flags [S.],seq 3467781056,ack 902832277,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 396158772,sackOK,eol],length 0
10:29:16.396349 IP localhost.ndmp> localhost.56348:Flags [S.],seq 2666080832,ack 2161003110,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 396158772,sackOK,eol],length 0
10:29:16.396366 IP localhost.ndmp> localhost.56350:Flags [S.],seq 2467582351,ack 1318035541,win 65535,options [mss 16344,nop,wscale 4,nop,nop,TS val 396158772 ecr 396158772,sackOK,eol],length 0
10:29:16.396375 IP localhost.56347> localhost.ndmp:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396381 IP localhost.56351> localhost.ndmp:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396386 IP localhost.56349> localhost.ndmp:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396391 IP localhost.56348> localhost.ndmp:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396398 IP localhost.56350> localhost.ndmp:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396408 IP localhost.ndmp> localhost.56347:Flags [R],seq 2871094528,win 0,length 0
10:29:16.396413 IP localhost.ndmp> localhost.56351:Flags [R],seq 3931313021,win 0,length 0
10:29:16.396419 IP localhost.56347> localhost.ndmp:Flags [P.],seq 1:1001,ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 1000
10:29:16.396424 IP localhost.56351> localhost.ndmp:Flags [P.],seq 1:1001,ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 1000
10:29:16.396429 IP localhost.ndmp> localhost.56349:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0 10:29:16.396435 IP localhost.ndmp> localhost.56348:Flags [R],seq 2666080833,win 0,length 0
10:29:16.396441 IP localhost.ndmp> localhost.56350:Flags [。],ack 1,win 9186,options [nop,nop,TS val 396158772 ecr 396158772],length 0
10:29:16.396454 IP localhost.ndmp> localhost.56347:Flags [R],seq 2871094528,win 0,length 0
10:29:16.396460 IP localhost.ndmp> localhost.56351:Flags [R],seq 3931313021,win 0,length 0
从 unix网络编程,connect()
将启动 3次握手程序,并在服务器发送 syn&& ACK
从tcpdump
输出,前10行告诉服务器回复syn& sck虽然积压是2.稍后,客户端发送上次确认,然后服务器返回。
在我看来,连接返回值!= -1表示建立连接&客户端能够发送数据。但上面的日志显示它不会那样工作。
所以有人能告诉我哪个正确?
答案 0 :(得分:2)
最后,在花时间谷歌搜索之后,我得到了上述行为的解释。
我已查看linux manual并显示:
注释
使用Linux 2.2改变了TCP套接字上的backlog参数的行为。现在它为完全建立的套接字等待接受指定队列长度,而不是 不完整连接的数量要求。可以使用/ proc / sys / net / ipv4 / tcp_max_syn_backlog设置不完整套接字的队列的最大长度。启用syncookies时,没有逻辑最大长度,并忽略此设置。有关更多信息,请参阅tcp(7)。
另外,在freebsd manual中{(3}}不会提供任何详细信息,但由于两个操作系统都基于bsd ^。^):
请注意,在FreeBSD 4.5 之前的和介绍的syncache , backlog参数还确定了不完整连接的长度 queue ,它在完成TCP 3-way的过程中持有TCP套接字 握手。这些不完整的连接现在完全 syncache ,队列长度不受影响。膨胀的积压值 不再需要帮助处理拒绝服务攻击。
总之,积压行为更改的原因似乎是保护服务免受 syn flood攻击。
答案 1 :(得分:0)
当您尝试在损坏/关闭的管道上发送数据时,会收到SIGPIPE信号。 根据您的tcpdump数据并按照您的解释:
connect实际上在客户端程序中返回OK。我敢肯定,因为所有连接都已建立好,三次握手完成。问题是,之后您立即尝试发送数据,我敢打赌您尝试在每个套接字中多次发送数据。我假设每个线程处理一个套接字。线程尝试使用端口56347或56351在套接字上发送数据的第二个或第三个(或更多)时间,管道因服务器已收到RESET而中断,操作系统将信号SIGPIPE发送到进程。 / p>
监听backlog似乎在您的服务器中正常工作。似乎3个连接被正确处理,只有2个被拒绝。服务器可能足够快地处理第一个连接,以便在积压中留下下一个2。最后两个无法成功,因为积压太小(2)。