【问题标题】:socket fin after syn ack on centos 7centos 7上syn ack后的socket fin
【发布时间】:2016-08-18 06:22:21
【问题描述】:

我用epoll写了一个tcp服务器,在Ubuntu上可以正常工作,但是在CentOS7上偶尔会发生奇怪的事情。

客户端a尝试连接服务器b,连接已建立, 客户端的端口是59298,服务端的端口是8802,服务端的socketfd是16。

[同步]

[syn,ack]

[确认]

同时服务器读取事件,返回值为零,sockfd 相同,即 16,与之前建立的连接相同,告诉 a 和 b 之间的连接已关闭。服务器使用不同的端口向客户端发送一个 [rst,ack] 包,即 59191。为什么会发生这种情况?是centos内核的bug吗?

我的代码与下面的非常相似。

       #define MAX_EVENTS 10
       struct epoll_event ev, events[MAX_EVENTS];
       int listen_sock, conn_sock, nfds, epollfd;

       /* Set up listening socket, 'listen_sock' (socket(),
          bind(), listen()) */

       epollfd = epoll_create(10);
       if (epollfd == -1) {
           perror("epoll_create");
           exit(EXIT_FAILURE);
       }

       ev.events = EPOLLIN;
       ev.data.fd = listen_sock;
       if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
           perror("epoll_ctl: listen_sock");
           exit(EXIT_FAILURE);
       }

       for (;;) {
           nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
           if (nfds == -1) {
               perror("epoll_pwait");
               exit(EXIT_FAILURE);
           }

           for (n = 0; n < nfds; ++n) {
               if (events[n].data.fd == listen_sock) {
                   conn_sock = accept(listen_sock,
                                   (struct sockaddr *) &local, &addrlen);
                   if (conn_sock == -1) {
                       perror("accept");
                       exit(EXIT_FAILURE);
                   }
                   setnonblocking(conn_sock);
                   ev.events = EPOLLIN | EPOLLET;
                   ev.data.fd = conn_sock;
                   if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                               &ev) == -1) {
                       perror("epoll_ctl: conn_sock");
                       exit(EXIT_FAILURE);
                   }
               } else {
                   do_use_fd(events[n].data.fd);
               }
           }
       }

这是我的 tcpdump 结果。

【问题讨论】:

    标签: linux sockets tcpdump epoll


    【解决方案1】:

    我在阅读 man epoll 后得到了原因。这是由于代码不合适而发生的。

     epoll_ctl(epollfd_, EPOLL_CTL_DEL, sockfd, &ev)
    

    似乎github上关于epoll的正确用法示例很少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 2015-07-04
      • 2013-07-05
      相关资源
      最近更新 更多