监听socket设置 为非阻塞时,在接收到连接请求时,连接socket并没有将阻塞性继承下来。以具体的代码 为例:
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#define MAX_EPOLL_EVENTS 10
int main(int argc, char*argv[])
{
if (argc < 2)
{
printf("usage:cmd port\n");
exit(-1);
}
int epoll_fd = epoll_create(10);
sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[1]));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0)
{
perror("socket error");
exit(-1);
}
if (bind(listenfd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind error");
exit(-1);
}
printf("listenfd=%d\n", listenfd);
epoll_event event;
memset(&event, 0, sizeof(event));
event.data.fd = listenfd;
event.events = EPOLLIN | EPOLLET;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listenfd, &event) < 0)
{
perror("epoll_ctl error");
exit(-1);
}
int flags = fcntl(listenfd, F_GETFL, 0);
flags |= O_NONBLOCK;
if (fcntl(listenfd, F_SETFL, flags) < 0)
{
perror("fcntl error");
exit(-1);
}
flags = fcntl(listenfd, F_GETFL, 0);
printf("flag :%d\n", flags & O_NONBLOCK);
listen(listenfd, 5);
epoll_event events[MAX_EPOLL_EVENTS];
while (1)
{
int n = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, -1);
if (n > 0)
{
printf("n=%d\n", n) ;
for (int i = 0; i < n; i++)
{
int fd = events[i].data.fd;
printf("fd=%d\n", fd);
if ((events[i].events & EPOLLIN) && fd == listenfd)
{
printf("fd == listenfd\n");
int connfd = accept(fd, NULL, NULL);
if (connfd > 0)
{
int flags = fcntl(connfd, F_GETFL, 0);
printf("flag & O_NONBLOCK=%d\n", flags & O_NONBLOCK);
}
}
}
}
}
return 0;
}
输出 为:
listenfd=4
flag :2048
n=1
fd=4
fd == listenfd
flag & O_NONBLOCK=0