监听套接字不可写?

在分析libevent源码并实现自己的网络库的时候想到这样一个问题:为什么注册事件的时候总是替换着注册EPOLLIN和EPOLLOUT呢?

于是我就在接收新连接注册新连接的监听事件时把EPOLLIN和EPOLLOUT都注册上了,结果就是,一直进EPOLLOUT,也就是说连接的套接字一直都可以可写的,这又引出另一个问题,epfd中注册的fd只有监听套接字时没有一直进EPOLLOUT呢?难道监听的套接字不可写?于是就有了这篇测试的文章。

既然怀疑,那就写个demo试试嘛。

 1 #include <unistd.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <netinet/in.h>
 5 #include <arpa/inet.h>
 6 
 7 #include <stdio.h>
 8 #include <string.h>
 9 #include <errno.h>
10 
11 int main(int argc, char **argv)
12 {
13     printf("start\n");
14     int fd = socket(AF_INET, SOCK_STREAM, 0);
15     if (fd == -1)
16     {
17         printf("socket\n");
18         return -1;
19     }
20 
21     struct sockaddr_in addr;
22     memset(&addr, 0, sizeof(addr));
23     addr.sin_family = AF_INET;
24     addr.sin_addr.s_addr = INADDR_ANY;
25     addr.sin_port = htons(8080);
26 
27     if (-1 == bind(fd, (struct sockaddr*)&addr, sizeof(addr)))
28     {
29         printf("bind\n");
30         return -1;
31     }
32 
33     if (-1 == listen(fd, 5))
34     {
35         printf("listen\n");
36         return -1;
37     }
38 
39     int iRet = send(fd, "hello", 5, 0);
40     if (-1 == iRet)
41     {
42         printf("send\n");
43         return -1;
44     }
45     else if (0 == iRet)
46     {
47         printf("Send zero data\n");
48     }
49     else
50     {
51         printf("Succ\n");
52     }
53 
54     printf("End\n");
55     return 0;
56 }

用gdb执行该程序:(至于为什么用gdb执行该程序,将在另一篇文章中说)

这里可以看到,收到了一个SIGPIPE的信号。

关于SIGPIPE这个信号的意思,man pages有这样一个解释:

意思就是说往一个没有读取端的pipe写数据,这就证实了我们的猜测,监听套接字是不可写的。

posted @ 2017-01-08 01:42  冷冰若水  阅读(561)  评论(0编辑  收藏  举报