Chinaunix

标题: Linux Kernel 2.6,listen(5),永不 accept,到底能建立成功多少个连接? [打印本页]

作者: flw    时间: 2008-09-02 17:24
标题: Linux Kernel 2.6,listen(5),永不 accept,到底能建立成功多少个连接?
  1. $ perl -MIO::Socket -e '$s=new IO::Socket::INET( LocalPort => 9999, Listen => 5 ); sleep(1) while 1'
复制代码
  1. $ perl -MIO::Socket -le 'foreach(1..100000){ $c=new IO::Socket::INET( PeerAddr => "127.0.0.1:9999" ); redo unless $c; push @c, $c; print }'
复制代码
  1. $ netstat -nat | grep EST | grep 9999 | wc -l
复制代码

数字一直在涨。

[ 本帖最后由 flw 于 2008-9-2 17:37 编辑 ]
作者: gawk    时间: 2008-09-02 17:27
等待结果
作者: chenzhanyiczy    时间: 2008-09-02 17:31
只有5个吧,listen是建立连接,只是没有accpet
作者: 5毛党党员    时间: 2008-09-02 17:31
这个会把机器搞死吗?不敢拿服务器试
作者: cookis    时间: 2008-09-02 17:43
具体什么版本
我前一阵就遇到一个问题
1. 在RH As5 (kernel 2.26.1上. 当进程可创建的句柄数据超范围时. epoll_wait会出现死循环..
    认识最后一个没有accept的事件永远可读.
    当在2.26.24上就没事.
当然跟你这个问题不一样.

但根据我所掌握的知识来判断. 应该是5吧. 这个就是内核创建的建立连接的队列大小. accept一次. 队列减少一个成员.
如果没有accept. 那队列永远满着. 应该不会覆盖掉.

[ 本帖最后由 cookis 于 2008-9-2 17:45 编辑 ]
作者: benbenr    时间: 2008-09-02 17:47
涨到多少了?系统应该是有上限的。
作者: cookis    时间: 2008-09-02 17:47
你在两台机器上试呢.. 本机内可能不用三次握手呢.
作者: chenzhanyiczy    时间: 2008-09-02 17:50
张到5个的时候,其他的就拒绝掉了,所以只有5个
作者: flw    时间: 2008-09-02 17:51
原帖由 chenzhanyiczy 于 2008-9-2 17:31 发表
只有5个吧,listen是建立连接,只是没有accpet

我现在测试的是,一开始,一口气建立了 8 个连接。
然后,以大约 3 到 5 秒钟一个的速度,慢慢增长。
因为长的很慢,所以现在还在涨。
作者: flw    时间: 2008-09-02 17:52
原帖由 chenzhanyiczy 于 2008-9-2 17:50 发表
张到5个的时候,其他的就拒绝掉了,所以只有5个

先试试吧。可能和你想的不一样。
作者: lzs45    时间: 2008-09-02 17:53
关注,理论上是5个,需要实验验证
作者: cookis    时间: 2008-09-02 17:54

  1. tcp        0      0 192.168.1.47:9999           192.168.1.49:47187          SYN_RECV    -
  2. tcp        0      0 192.168.1.47:9999           192.168.1.49:47186          SYN_RECV    -
  3. tcp        0      0 192.168.1.47:9999           192.168.1.49:47184          ESTABLISHED -
  4. tcp        0      0 192.168.1.47:9999           192.168.1.49:47185          ESTABLISHED -
  5. tcp        0      0 192.168.1.47:9999           192.168.1.49:47183          ESTABLISHED -
  6. tcp        0      0 192.168.1.47:9999           192.168.1.49:47181          ESTABLISHED -
  7. tcp        0      0 192.168.1.47:9999           192.168.1.49:47182          ESTABLISHED -
  8. tcp        0      0 192.168.1.47:9999           192.168.1.49:47180          ESTABLISHED -
复制代码

这是两台机器上的结果.. 果然超出5了.  不过我这增长的是SYN_RECV状态的连接.
作者: flw2    时间: 2008-09-02 17:54
原帖由 cookis 于 2008-9-2 17:47 发表
你在两台机器上试呢.. 本机内可能不用三次握手呢.

本机为什么不3次握手?
作者: cookis    时间: 2008-09-02 17:55
原帖由 flw2 于 2008-9-2 17:54 发表

本机为什么不3次握手?



我是说可能.. 但看我上面的贴了..明显在本机和分开测试结果是不一样的.
作者: flw    时间: 2008-09-02 17:56
哦,我知道了。分开在两台机器上就看得很清楚了。
server 端是 6 个,多余的应该是清除了吧(timeout?)。
客户端一直在涨。
作者: 5毛党党员    时间: 2008-09-02 17:57
为啥我的本机也在涨?
作者: 5毛党党员    时间: 2008-09-02 17:58
tcp        0      0 127.0.0.1:9999              127.0.0.1:37476             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37475             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37474             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37473             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37472             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37471             ESTABLISHED
tcp        0      0 127.0.0.1:37536             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37541             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37530             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37531             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37535             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37522             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37521             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37526             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37527             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37514             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37515             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37504             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37505             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37510             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37511             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37499             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37496             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37500             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37491             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37495             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37492             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37484             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37485             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37474             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37475             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37472             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37473             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37478             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37479             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37476             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37477             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37471             127.0.0.1:9999              ESTABLISHED
作者: cookis    时间: 2008-09-02 17:59
估计每个状态都有一个超时值.. state machine.
作者: flw2    时间: 2008-09-02 17:59
flw能否有个C的,我看不懂,特别是第一个,我可以看看代码是怎么回事
作者: chenzhanyiczy    时间: 2008-09-02 18:01
SYN_RECV状态可以理解,为什么会超过5个呢?也真是奇怪
作者: cookis    时间: 2008-09-02 18:02
原帖由 flw 于 2008-9-2 17:56 发表
哦,我知道了。分开在两台机器上就看得很清楚了。
server 端是 6 个,多余的应该是清除了吧(timeout?)。
客户端一直在涨。



哪里有多余的?
我觉得第六个就是. 没插入到队列里. 处理未受管理的状态. 所以才会出现6个. 其他的都是处于SYN_RECV状态.
就是服务器没有向客户端发SYN(因为它的队列已经满了). 但客户端一直尝试创建连接. 打印错误码看看呢.
作者: benbenr    时间: 2008-09-02 18:02
这个试验不是要创建连接数么?

本机的确没有tcp的3次握手,貌似连局域网也会存在点小问题的。

连接个数的话应该是和linux所打开的文件个数有关。

listen的话,我以为是同时只能有5个连接,多与的就等待了?好像不对哦。。。

[ 本帖最后由 benbenr 于 2008-9-2 18:04 编辑 ]
作者: benbenr    时间: 2008-09-02 18:04
不对。listen本来就是等待连接的队列。超过这个就异常了呀。
作者: flw    时间: 2008-09-02 18:04
原帖由 flw2 于 2008-9-2 17:59 发表
flw能否有个C的,我看不懂,特别是第一个,我可以看看代码是怎么回事

  1. flw@waker:~$ cat listen.c
  2. # include <stdio.h>
  3. # include <sys/types.h>
  4. # include <sys/socket.h>
  5. # include <netinet/in.h>

  6. int main( int argc, char *argv[] )
  7. {
  8.     int backlog;
  9.     int sock;
  10.     struct sockaddr_in addr;
  11.     int ret;

  12.     if ( argc != 2 ){
  13.         printf( "Usage: %s <backlog>\n", argv[0] );
  14.         printf( "use 5 for backlog\n" );
  15.         backlog = 5;
  16.     }
  17.     else{
  18.         backlog = atoi( argv[1] );
  19.     }

  20.     sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
  21.     if ( sock == -1 ){
  22.         perror( "socket" );
  23.         return -1;
  24.     }

  25.     addr.sin_family = AF_INET;
  26.     addr.sin_port = htons( 9999 );
  27.     addr.sin_addr.s_addr = INADDR_ANY;
  28.     ret = bind( sock, (struct sockaddr *)&addr, sizeof(addr) );
  29.     if ( ret == -1 ){
  30.         perror( "bind" );
  31.         return -1;
  32.     }

  33.     ret = listen( sock, backlog );
  34.     if ( ret == -1 ){
  35.         perror( "listen" );
  36.         return -1;
  37.     }

  38.     while(1){
  39.         sleep(1);
  40.     }
  41. }
  42. flw@waker:~$
复制代码

作者: 5毛党党员    时间: 2008-09-02 18:05
server端一直是只有6个吧?

涨的是client端一直不停尝试连接的
作者: yecheng_110    时间: 2008-09-02 18:07
原帖由 chenzhanyiczy 于 2008-9-2 17:31 发表
只有5个吧,listen是建立连接,只是没有accpet

不会只有5个的

Figure 4.10. Actual number of queued connections for values of backlog.

123.JPG (21.84 KB, 下载次数: 75)

123.JPG

作者: cookis    时间: 2008-09-02 18:15
标题: 回复 #26 yecheng_110 的帖子
哦..这就是为什么一开始上来 是 8个了.
作者: scutan    时间: 2008-09-02 18:16
刚刚测试了一下, 在server端连接状态为ESTABLISHED的只有五个, 其余的都为SYN_RECV状态.
作者: flw2    时间: 2008-09-02 18:20
我这里得到的是47
但是不知道netstat 看到的连接ESTABLISHED的个数到底什么意思
而且很多connect最后都是超时返回失败的

回家了先
作者: scutan    时间: 2008-09-02 18:21
原帖由 scutan 于 2008-9-2 18:16 发表
刚刚测试了一下, 在server端连接状态为ESTABLISHED的只有五个, 其余的都为SYN_RECV状态.


而且在过了一段时间之后所有为SYN_RECV状态的连接都会断掉. 即是说如果不将已经建立了三次连接的用accept取走的话, 那么处于SYN_RECV状态的连接会在一段时间之后消失.

我想可能是因为不断地有连接消失, 所以才能够不断地去连接它, 而后面连接数增长的时间较慢, 是因为SYN_RECV状态的连接的取消需要一段时间.
作者: scutan    时间: 2008-09-02 18:22
flw老大, 你可以看一看, 虽然可以一直接收连接, 但是在服务器端处于SYN_RECV状态的连接数基本上是不会变的.不断地有SYN_RECV连接被取消, 所以就可以不断地进行新的连接.
作者: flw    时间: 2008-09-02 18:25
奇怪啊,为什么服务端是 SYN_RECV,客户端却是 ESTABLISHED 呢?

[ 本帖最后由 flw 于 2008-9-2 18:27 编辑 ]
作者: flw    时间: 2008-09-02 18:28
原帖由 scutan 于 2008-9-2 18:16 发表
刚刚测试了一下, 在server端连接状态为ESTABLISHED的只有五个, 其余的都为SYN_RECV状态.

应该是 6 个吧。
作者: flw    时间: 2008-09-02 18:29
原帖由 scutan 于 2008-9-2 18:21 发表

而且在过了一段时间之后所有为SYN_RECV状态的连接都会断掉. 即是说如果不将已经建立了三次连接的用accept取走的话, 那么处于SYN_RECV状态的连接会在一段时间之后消失.

我想可能是因为不断地有连接消失, ...

嗯,我同意。
作者: scutan    时间: 2008-09-02 18:31
原帖由 flw 于 2008-9-2 18:28 发表

应该是 6 个吧。


我的机器上最多只有5个是ESTABLISHED状态. 后面来的全是SYN_RECV状态了.
作者: flw    时间: 2008-09-02 18:33
原帖由 scutan 于 2008-9-2 18:31 发表

我的机器上最多只有5个是ESTABLISHED状态. 后面来的全是SYN_RECV状态了.

你再数数。
注意数之前把 server 程序重启一下。
作者: scutan    时间: 2008-09-02 18:42
原帖由 flw 于 2008-9-2 18:33 发表

你再数数。
注意数之前把 server 程序重启一下。


重启之后数了一下, 确实是只有5个ESTABLISHED.

下面是图片:

11111.jpg (21.26 KB, 下载次数: 55)

test

test

作者: flw    时间: 2008-09-02 18:47
奇怪了,你是啥系统啊?
作者: scutan    时间: 2008-09-02 18:54
标题: 回复 #38 flw 的帖子
FC 6 内核是 2.6.18, 我晚点用另外的机器试试看.
作者: yecheng_110    时间: 2008-09-02 21:34
To understand the backlog argument, we must realize that for a given listening socket, the kernel maintains two queues :

1.An incomplete connection queue, which contains an entry for each SYN that has arrived from a client for which the server is awaiting completion of the TCP three-way handshake. These sockets are in the SYN_RCVD state .

2.A completed connection queue, which contains an entry for each client with whom the TCP three-way handshake has completed. These sockets are in the ESTABLISHED state .

The backlog argument to the listen function has historically specified the maximum value for the sum of both queues.

Berkeley-derived implementations add a fudge factor to the backlog: It is multiplied by 1.5

When a SYN arrives from a client, TCP creates a new entry on the incomplete queue and then responds with the second segment of the three-way handshake: the server's SYN with an ACK of the client's SYN (Section 2.6). This entry will remain on the incomplete queue until the third segment of the three-way handshake arrives (the client's ACK of the server's SYN), or until the entry times out. (Berkeley-derived implementations have a timeout of 75 seconds for these incomplete entries.)

If the queues are full when a client SYN arrives, TCP ignores the arriving SYN (pp. 930–931 of TCPv2); it does not send an RST. This is because the condition is considered temporary, and the client TCP will retransmit its SYN, hopefully finding room on the queue in the near future. If the server TCP immediately responded with an RST, the client's connect would return an error, forcing the application to handle this condition instead of letting TCP's normal retransmission take over. Also, the client could not differentiate between an RST in response to a SYN meaning "there is no server at this port" versus "there is a server at this port but its queues are full."


Some implementations do send an RST when the queue is full. This behavior is incorrect for the reasons stated above, and unless your client specifically needs to interact with such a server, it's best to ignore this possibility. Coding to handle this case reduces the robustness of the client and puts more load on the network in the normal RST case, where the port really has no server listening on it.

[ 本帖最后由 yecheng_110 于 2008-9-2 22:05 编辑 ]
作者: yecheng_110    时间: 2008-09-02 21:41
Linux ubuntu 2.6.22-14-generic #1 SMP Tue Feb 12 02:46:46 UTC 2008 x86_64 GNU/Linux

netstat -nat | grep EST | grep 9999 | awk '$4=="127.0.0.1:9999"' |wc -l
一直是6
completed connection queue的长度应该是6
netstat -nat | grep SYN_RECV | grep 9999 | awk '$4=="127.0.0.1:9999"' |wc -l
这个最大是16
incomplete connection queue的长度可能是16
而且隔一段时间会变少然后再增加到16
这个时间应该就是a timeout of 75 seconds

netstat -nat | grep 9999 | awk '$5=="127.0.0.1:9999"'|wc -l
这个和第二段的代码保持一致的增加 比第二段代码的输出多1
就是多SYN_SENT这行

上一贴是unp上摘抄的内容
这是对照着的实验 应该和理论是吻合的

[ 本帖最后由 yecheng_110 于 2008-9-2 22:25 编辑 ]
作者: cugb_cat    时间: 2008-09-02 21:53
原帖由 yecheng_110 于 2008-9-2 21:34 发表
To understand the backlog argument, we must realize that for a given listening socket, the kernel maintains two queues :

1.An incomplete connection queue, which contains an entry for each SYN  ...

恩,这么回事啊
作者: flw2    时间: 2008-09-02 21:57
的 ddd
原帖由 flw 于 2008-9-2 18:25 发表
奇怪啊,为什么服务端是 SYN_RECV,客户端却是 ESTABLISHED 呢?


linux 2.6.26.3的结果如下,2.6.11貌似是一样的,估计版本之间没什么差别

这是linux判断是否超出backlog的方法
比如backlog 是5,那么真时的连接允许保持6条,sk_ack_backlog = 0为默认值
再第7次连接时才返回真(第一次为0,..第6次为5,5==5)
static inline int sk_acceptq_is_full(struct sock *sk)
{
        return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}

对于别的backlog类似,这可能是为了处理backlog == 0的情况(unp说对于0的解释不同实现不同,这就是linux的解释,至少允许1个连接)

为了说明情况我以backlog为1为例子,为5也一样,但是省的改flw给的c代码

当第一个connect来时,ok连接成功,sk_ack_backlog(0) > sk_max_ack_backlog(1) 不成立
第2个连接时,连接一样成功  sk_ack_backlog(1) > sk_max_ack_backlog(1) 不成立

到第3个时,full了,这个条件的判断是在收到connect发出3次握手中的第3个包,即ack包时检查的

代码如下

    listen_overflow:
        printk("%s %d: overflow\n", __func__, __LINE__);
        if (!sysctl_tcp_abort_on_overflow) {
            inet_rsk(req)->acked = 1;
            return NULL;
        }

    embryonic_reset:
        printk("%s %d: reset\n", __func__, __LINE__);
        NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
        if (!(flg & TCP_FLAG_RST))
            req->rsk_ops->send_reset(sk, skb);

        inet_csk_reqsk_queue_drop(sk, req, prev);
        return NULL;




printk是我加的
代码我没有继续跟踪,但是很明显:

如果sysctl_tcp_abort_on_overflow为0 (默认值/proc/sys/net/ipv4/tcp_abort_on_overflow)是,那么只是是丢弃最后的ack包(当然客户端不会知道,这也是flw说的客户认为连接的原因,客户ack出去就连接完成了),后果和服务器没收到ack包是一样的,如果客户这个时候直接read,write,服务器可想而知,会重传syn-ack包,因为它“没收到”ack(即它还在等ack),事实是,即使客户不操作,服务器也会重发syn-ack,原因很简单,3次握手要完成

如果sysctl_tcp_abort_on_overflow不为0,那么直接rst了,当然connect不会知道,基于同样的理由,connect已经返回了,读写时就会知道被reset这个事实了


这些我想都是可以完全试验的,但是看代码以及printk,加上抓包,已经很明显了
作者: flw2    时间: 2008-09-02 22:03
真是感叹实现者的工作,丢弃ack的代价较小,内核期待用户马上accept,所以丢掉ack并不会导致连接断开,

我测试的结果就是来自flw的文件,connect代码加在bind前,注释掉后面的,看起来比unp提到linux2.4的结果少1
0-2
1-3
作者: aoegiss    时间: 2008-09-02 22:23
标题: 回复 #43 flw2 的帖子
怒赞
作者: flw    时间: 2008-09-02 22:39
原帖由 flw 于 2008-9-2 18:25 发表
奇怪啊,为什么服务端是 SYN_RECV,客户端却是 ESTABLISHED 呢?

哦,应该是服务端已经给客户端发过 syn+ack 了,
因此客户端已经进入 established 了。
但是服务端因为 listen queue 满了,
所以仍然维持 syn_recv 状态。
作者: timespace    时间: 2008-09-02 22:40
以前用Solaris 10和Linux 2.6.9测试过backlog = 1的情况:
        Solaris 是典型的教科书实现,和UNPV1的描述是一致的,最大排队的连接和最大完成连接都是2,也就是完成两个连接后收到SYN时,服务端丢弃SYN,所以也没有回送SYN和ACK,最终就是客户端TIMEOUT
        Linux就和大家看到的类似,服务端有两个完成连接和一个SYN_RCVD状态的未完成连接,最大排队连接数为3而最大完成连接数为2,SYN_RCVD的连接等待ACK超时后,服务端又可以接收新的SYN,不过服务端始终都是SYN_RCVD,客户端是ESTABLISHED,周而复始。。。,模拟个TIMEOUT不容易啊
作者: flw    时间: 2008-09-02 22:41
标题: 回复 #43 flw2 的帖子
嗯,果然和我想的是一样的。
作者: system888net    时间: 2008-09-03 12:49
此事虽早有定论,但还是要赞一下参与测试和思考发言的各位大拿的精神.
作者: 库鲁特    时间: 2008-09-03 21:21
提示: 作者被禁止或删除 内容自动屏蔽
作者: zhiwood    时间: 2008-09-03 22:58
我有个疑问,按照40楼的解释,server离开syn_recv的主动权在客户端,就是服务器等待客户端的ack. 如果在内部网连接很好的情况下,客户端没道理等很长时间才发第三个ack给server. 因此server上的netstat应该只会显示established状态, syn_recv状态由于时间太短,很难被观察到。incomplete的连接应该很少发生才是,但是看样子好象syn_recv在服务器上经常发生,这是怎么回事?
作者: flw    时间: 2008-09-03 23:17
原帖由 zhiwood 于 2008-9-3 22:58 发表
我有个疑问,按照40楼的解释,server离开syn_recv的主动权在客户端,就是服务器等待客户端的ack. 如果在内部网连接很好的情况下,客户端没道理等很长时间才发第三个ack给server. 因此server上的netstat应该只会 ...

是因为 completed queue 满了,因此服务器会丢失第三个 ACK,而保持状态为 SYN_RECV。

其实也可以不保持,而是 REST 连接,通过 /proc 下的那个文件可以控制。
作者: chenzhanyiczy    时间: 2008-09-03 23:42
问一下: 什么是REST 连接?
作者: qliu00    时间: 2008-09-03 23:50
标题: 回复 #10 flw 的帖子
不敢试,别机子死掉了

既然版主说了、,就来试试

tcp        0      0 127.0.0.1:9999              127.0.0.1:37475             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37474             ESTABLISHED
tcp        0      0 127.0.0.1:9999              127.0.0.1:37473             ESTABLISHED
tcp        0      0 127.0.0.1:37484             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37504             127.0.0.1:9999              ESTABLISHED
tcp        0      0 127.0.0.1:37476             127.0.0.1:9999              ESTABLISHED

server 端和客户端共握手6次,就停止了

[ 本帖最后由 qliu00 于 2008-9-4 22:59 编辑 ]
作者: yecheng_110    时间: 2008-09-04 09:49
原帖由 chenzhanyiczy 于 2008-9-3 23:42 发表
问一下: 什么是REST 连接?

就是发reset包
作者: chenzhanyiczy    时间: 2008-09-04 11:18
原帖由 yecheng_110 于 2008-9-4 09:49 发表

就是发reset包


我的意思是reset指的是什么意思?指:重新连接?
作者: yecheng_110    时间: 2008-09-04 11:30
原帖由 chenzhanyiczy 于 2008-9-4 11:18 发表


我的意思是reset指的是什么意思?指:重新连接?

表示没有提供这个服务
断开连接
作者: chenzhanyiczy    时间: 2008-09-04 11:47
reset在tcp head的表现是rst=1??
作者: yecheng_110    时间: 2008-09-04 11:50
原帖由 chenzhanyiczy 于 2008-9-4 11:47 发表
reset在tcp head的表现是rst=1??

是的
作者: koolcoy    时间: 2008-09-06 15:33
我记得在配置linux内核的时候有个SYN cookie选项。 这个选项应该会影响到内核的行为吧。
作者: mouse2000    时间: 2008-09-06 21:43
呵呵,通过这个帖子向版主们学习努力寻找问题答案的精神~!
作者: FreeB_U    时间: 2008-10-06 16:14
这个可以参考<tcp/ip协议详解(卷一)>

不同的系统对backlog值的理解是不一样的。。

BSD把 backlog*3/2  当作队列的的最大值(已建立链接的队列+未建立链接的队列)     

也就是说:如果backlog=5  那么最多可以有8个连接。。。(其它的系统未必遵循这个规则)


当然 。现在的 backlog可以设置的很大,,也就是我们可以编程时把它设置为一个很大的值,,但是系统并不会因为这样而使用这个值,
它会使用系统所支持的最大的值,,,可以在socket.h文件里看到最大值的定义
作者: 空灵静世    时间: 2008-10-31 11:00
从tcpdump抓包的结果看,客户端每9秒建立两条连接,也就是服务器每9秒响应两条联接(以前在不同的机器上我抓包每3秒建立一条连接,今天不知道为什么抓不出来了)
抓包如下:
tcpdump -i lo port 9999 -r hw.tcp|grep 32790
reading from file hw.tcp, link-type EN10MB (Ethernet)
10:30:15.289296 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767 <mss 16396,sackOK,timestamp 114528 0,nop,wscale 3>
10:30:18.288480 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767 <mss 16396,sackOK,timestamp 117528 0,nop,wscale 3>
10:30:24.288311 IP 192.168.0.130.32790 > 192.168.0.130.9999: S 1650969640:1650969640(0) win 32767 <mss 16396,sackOK,timestamp 123528 0,nop,wscale 3>
10:30:24.288343 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767 <mss 16396,sackOK,timestamp 123528 123528,nop,wscale 3>
10:30:24.288362 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 123528 123528>
10:30:27.686649 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767 <mss 16396,sackOK,timestamp 126927 123528,nop,wscale 3>
10:30:27.686690 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 126927 126927,nop,nop,sack sack 1 {0:1} >
10:30:33.685473 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767 <mss 16396,sackOK,timestamp 132927 126927,nop,wscale 3>
10:30:33.685509 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 132927 132927,nop,nop,sack sack 1 {0:1} >
10:30:45.686130 IP 192.168.0.130.9999 > 192.168.0.130.32790: S 1652955109:1652955109(0) ack 1650969641 win 32767 <mss 16396,sackOK,timestamp 144929 132927,nop,wscale 3>
10:30:45.686160 IP 192.168.0.130.32790 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 144929 144929,nop,nop,sack sack 1 {0:1} >
bash-3.00# tcpdump -i lo port 9999 -r hw.tcp|grep 32791
reading from file hw.tcp, link-type EN10MB (Ethernet)
10:30:24.288493 IP 192.168.0.130.32791 > 192.168.0.130.9999: S 1661414239:1661414239(0) win 32767 <mss 16396,sackOK,timestamp 123528 0,nop,wscale 3>
10:30:24.288509 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767 <mss 16396,sackOK,timestamp 123529 123528,nop,wscale 3>
10:30:24.288523 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 123529 123529>
10:30:27.686663 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767 <mss 16396,sackOK,timestamp 126927 123529,nop,wscale 3>
10:30:27.686700 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 126927 126927,nop,nop,sack sack 1 {0:1} >
10:30:33.685485 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767 <mss 16396,sackOK,timestamp 132927 126927,nop,wscale 3>
10:30:33.685517 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 132927 132927,nop,nop,sack sack 1 {0:1} >
10:30:45.886100 IP 192.168.0.130.9999 > 192.168.0.130.32791: S 1661567750:1661567750(0) ack 1661414240 win 32767 <mss 16396,sackOK,timestamp 145129 132927,nop,wscale 3>
10:30:45.886148 IP 192.168.0.130.32791 > 192.168.0.130.9999: . ack 1 win 4096 <nop,nop,timestamp 145129 145129,nop,nop,sack sack 1 {0:1} >

[ 本帖最后由 空灵静世 于 2008-10-31 11:14 编辑 ]
作者: linternt    时间: 2008-10-31 11:22
原帖由 flw 于 2008-9-2 17:52 发表

先试试吧。可能和你想的不一样。


我们写的服务程序,几分钟就死了,垃圾!

LDAP这样连一会也就完蛋了!一千多点的时候,基本就响应特别慢了!
作者: 空灵静世    时间: 2008-10-31 11:38
我更正上之前说的,当syn_recv没有开始退出之前,服务器会延迟9秒对客户端的syn进行回应(紧跟的下一条连接是及时回应),但当有syn_recv开始有退出的时候是延时三秒回应
三秒回应抓包如下:
tcpdump port 9999 -r hw7.tcp | grep 55145
reading from file hw7.tcp, link-type EN10MB (Ethernet)
11:33:35.354033 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: S 766929119:766929119(0) win 5840 <mss 1460,sackOK,timestamp 74113887 0,nop,wscale 2>
11:33:38.353957 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: S 766929119:766929119(0) win 5840 <mss 1460,sackOK,timestamp 74116887 0,nop,wscale 2>
11:33:38.354004 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792 <mss 1460,sackOK,timestamp 226608 74116887,nop,wscale 3>
11:33:38.354272 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74116887 226608>
11:33:42.153595 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792 <mss 1460,sackOK,timestamp 230408 74116887,nop,wscale 3>
11:33:42.153842 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74120688 230408,nop,nop,sack sack 1 {0:1} >
11:33:48.152723 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792 <mss 1460,sackOK,timestamp 236408 74120688,nop,wscale 3>
11:33:48.152932 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74126688 236408,nop,nop,sack sack 1 {0:1} >
11:34:00.350861 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55145: S 1149964455:1149964455(0) ack 766929120 win 5792 <mss 1460,sackOK,timestamp 248608 74126688,nop,wscale 3>
11:34:00.351157 IP pc-200805111531.unimassystem.com.55145 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74138888 248608,nop,nop,sack sack 1 {0:1} >
bash-3.00# tcpdump port 9999 -r hw7.tcp | grep 55146
reading from file hw7.tcp, link-type EN10MB (Ethernet)
11:33:38.354339 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: S 775886579:775886579(0) win 5840 <mss 1460,sackOK,timestamp 74116888 0,nop,wscale 2>
11:33:41.354160 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: S 775886579:775886579(0) win 5840 <mss 1460,sackOK,timestamp 74119888 0,nop,wscale 2>
11:33:41.354205 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792 <mss 1460,sackOK,timestamp 229609 74119888,nop,wscale 3>
11:33:41.354549 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74119888 229609>
11:33:45.552521 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792 <mss 1460,sackOK,timestamp 233808 74119888,nop,wscale 3>
11:33:45.552894 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74124087 233808,nop,nop,sack sack 1 {0:1} >
11:33:51.551634 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792 <mss 1460,sackOK,timestamp 239808 74124087,nop,wscale 3>
11:33:51.551956 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74130087 239808,nop,nop,sack sack 1 {0:1} >
11:34:03.549851 IP 192.168.0.130.9999 > pc-200805111531.unimassystem.com.55146: S 1152059511:1152059511(0) ack 775886580 win 5792 <mss 1460,sackOK,timestamp 251808 74130087,nop,wscale 3>
11:34:03.550073 IP pc-200805111531.unimassystem.com.55146 > 192.168.0.130.9999: . ack 1 win 1460 <nop,nop,timestamp 74142088 251808,nop,nop,sack sack 1 {0:1} >
bash-3.00#
作者: 空灵静世    时间: 2008-10-31 12:00
猜测下内核的做法:内核延时3秒后试图对客户端回应的时候监查syn_recv队列有无变化,有变化,发回应的syn,无变化则再等3秒,直到9秒,但为什么接下来的却能及时回应呢?
作者: chenzhanyiczy    时间: 2008-10-31 13:06
这个问题,要看内核的实现,不同的实现有不同的效果,可以参考unp,一般总的连接数是己连接数(经过TCP三次握手的)的1.5倍
作者: hightman    时间: 2008-11-11 17:53
client看到的是Established是不是因为您的服务器打开了syncookie之类(或PF中的syn-proxy)
作者: 寂寞不    时间: 2011-03-17 21:43
本帖最后由 寂寞不 于 2011-03-17 21:45 编辑

listen(int sockfd ,int  backlog);
backlog 能监听的客户端的个数,比如:
listen( sfd , 20);
我一般用20(想多一点可以多线程或者多进程),
就是说我监听的最多只有 20个,比如有 25 个客户同时请求链接!
那就只有 20 个客户握手成功(成功后排队等待处理)。剩下的5个就被抛弃。

如果处理器能力很强大!那就不用考虑backlog直接 =20。
作者: rong_bo    时间: 2013-02-27 14:14
这个帖子有价值。
作者: windoze    时间: 2013-02-27 14:24
listen(2)
NOTES:
...
The  behavior  of  the  backlog argument on TCP sockets changed with Linux 2.2.  Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of incomplete connection requests.  The maximum length of the queue for incomplete sockets can  be  set using  /proc/sys/net/ipv4/tcp_max_syn_backlog.   When  syncookies  are  enabled  there is no logical maximum length and this setting is ignored.  See tcp(7) for more information.

作者: eastany_op    时间: 2013-02-28 11:08
回复 1# flw


    看系统参数,
/proc/sys/下的net和ipv4中的 有限制最大长度的
超过限制就丢弃




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2