- 论坛徽章:
- 6
|
本帖最后由 瀚海书香 于 2014-02-18 15:40 编辑
回复 6# jiufei19
感谢斑竹的解答,但是我没有明白我的第2个问题斑竹是如何解答的,斑竹说的是:关于第二个,存在client端先bind,然后再connect的情况。已经在本地通过systemtap验证,我没有明白这个解释如何就解释了rskq_defer_accept在客户端被设置的场景?
场景是client端先bind到一个端口和ip,setsockopt(TCP_DEFER_ACCEPT),然后connect server,这个时候就会出现rskq_defer_accept=1的情况。
我在本地通过systemtap,在内核打点的方式验证了这种情况下,当收到server发来的syn/ack的时候,这个时候icsk->icsk->icsk_accept_queue.rskq_defer_accept=1.
client测试代码:- int main(int argc,char **argv)
- {
- int listenfd,connfd,opt=1;
- pid_t childpid;
- int i;
- socklen_t clilen;
- struct sockaddr_in servaddr;
- struct sockaddr_in realaddr;
- if (argc != 4) {
- printf("usage: %s bindip connectip connectport\n", argv[0]);
- return 0;
- }
- if ((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
- err_quit("socket error errno=%d", errno);
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family=AF_INET;
- inet_aton(argv[1], &(servaddr.sin_addr));
- servaddr.sin_port = htons(2014);
- opt = 1;
- setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- opt = 1;
- setsockopt(listenfd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &opt, sizeof(opt));
- if (bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))==-1)
- printf("bind error errno=%d\n", errno);
- bzero(&realaddr,sizeof(realaddr));
- realaddr.sin_family=AF_INET;
- realaddr.sin_port=htons(atoi(argv[3]));
- inet_pton(AF_INET,argv[2],&realaddr.sin_addr);
- if (connect(listenfd,(struct sockaddr*)&realaddr,sizeof(realaddr))==-1)
- printf("connect error errno=%d", errno);
- while(1)
- sleep(10);
- }
复制代码 systemtap验证代码:- %{
- #include <net/sock.h>
- #include <net/inet_connection_sock.h>
- %}
- function show_sock:long(skaddr:long)
- %{
- struct sock *sk = (struct sock*)(THIS->skaddr);
- struct inet_connection_sock *icsk = inet_csk(sk);
- printk("tcp_defer_accept=%d sk_write_pending=%d\n",
- icsk->icsk_accept_queue.rskq_defer_accept,
- sk->sk_write_pending);
- THIS->__retvalue = 1;
- %}
- probe kernel.function("tcp_rcv_synsent_state_process")
- {
- printf("Called function tcp_rcv_synsent_state_process\n")
- show_sock($sk);
- }
复制代码 |
|