设置socket套接字为非阻塞
int make_socket_non_blocking(int fd){//设置套接字为非阻塞模式
int flag = fcntl(fd, F_GETFL, 0);//获得文件状态标记
if(flag == -1)
return -1;
flag |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flag) == -1)//设置文件状态标记为O_NONBLOCK
return -1;
}
int rc = make_socket_non_blocking(listen_fd);
- fcntl()函数的使用
fcntl->file control,文件描述符控制函数,在网络编程中,它通常用来将文件设置为非阻塞,具体函数编写就是上面的函数#include <fcntl.h> int fcntl(int fd,int cmd); int fcntl(int fd,int cmd,long arg); int fcntl(int fd,int cmd,struct flock *lock); //该函数用来操作fd文件描述符,具体的操作cmd命令指定,可以对文件进行加锁等操作 //失败,则所有命令返回-1,成功则返回某个其他值 // F_DUPFD,返回的是新的文件描述符 // F_GETFL 取得文件描述符状态标志 //F_SETFL 设置文件描述符状态标志,参数arg为新标志,设置成功返回0, //O_NONBLOCK,非阻塞I/O flags = fcntl(sockfd, F_GETFL, 0); //获取文件的flags值。 fcntl(listen_fd, F_SETFL, flags | O_NONBLOCK); //设置成非阻塞模式; fcntl(listen_fd, F_SETEL, flags&~O_NONBLOCK);//设置成阻塞式I/O
基本上就这么用,其他的设置都是次要的,主要就是用来设置非阻塞。
-
讲一下非阻塞I/O和阻塞I/O的区别
对于消息队列消息的发送与接受::
读数据的函数有:read,recv,recvmsg,写的函数有:write,send,sendmsg。
读操作的实质:具体的接受数据并不是这些函数的调用导致的,而是系统底层自动完成的,它们的调用只是从底层缓冲区拷贝数据到我们指定的位置
读情况下:- 阻塞:
如果发现缓冲区没有数据会一直等待。
有数据就把数据读到用户缓冲区。 - 非阻塞:
没有数据就返回。
有数据就有多少读多少。
- 阻塞:
- 写情况下:
写的本质也不是发送操作,而是将数据从用户态拷贝到系统底层缓冲区,然后由系统发送。- 阻塞:
一直写直到数据全部写完,如果网络很拥塞,那也要等到写完才能返回(不过会中断)。 - 非阻塞:
能写多少写多少,如果网络很拥塞,没有足够内存来写,就不写。
- 阻塞: