在分析libevent源码并实现自己的网络库的时候想到这样一个问题:为什么注册事件的时候总是替换着注册EPOLLIN和EPOLLOUT呢?
于是我就在接收新连接注册新连接的监听事件时把EPOLLIN和EPOLLOUT都注册上了,结果就是,一直进EPOLLOUT,也就是说连接的套接字一直都可以可写的,这又引出另一个问题,epfd中注册的fd只有监听套接字时没有一直进EPOLLOUT呢?难道监听的套接字不可写?于是就有了这篇测试的文章。
既然怀疑,那就写个demo试试嘛。
1 #include2 #include 3 #include 4 #include 5 #include 6 7 #include 8 #include 9 #include 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 else50 {51 printf("Succ\n");52 }53 54 printf("End\n");55 return 0;56 }
用gdb执行该程序:(至于为什么用gdb执行该程序,将在另一篇文章中说)
这里可以看到,收到了一个SIGPIPE的信号。
关于SIGPIPE这个信号的意思,man pages有这样一个解释:
意思就是说往一个没有读取端的pipe写数据,这就证实了我们的猜测,监听套接字是不可写的。