网络编程中非阻塞的实现方式
一.设置套接字
1. fcntl
//文件从阻塞设置为非阻塞
int flag = fcntl(cfd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(cfd, F_SETFL, flag);
//文件从非阻塞设置为阻塞
int flags=fcntl(cfd, F_GETFL, 0);
flags &=~O_NONBLOCK;
fcntl(cfd, F_SETFL, flags);
2. socket
socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);//SOCK_NONBLOCK非阻塞模式
3. ioctl
int main() {int sockfd;int nb = 1; // 1表示启用非阻塞模式// 创建一个IPv4 TCP套接字sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("socket() failed");return 1;}// 设置套接字为非阻塞模式if (ioctl(sockfd, FIONBIO, &nb) < 0) {perror("ioctl() failed");return 1;}// 进一步的套接字操作...close(sockfd);return 0;
}
fcntl与ioctl的区别是什么?
ioctl():
ioctl() 是一个更底层的系统调用,适用于设备文件或套接字操作,在一些操作系统或设备驱动中使用时,它可以执行不同的控制操作,更多用于硬件设备控制。
fcntl():
fcntl() 是 POSIX 标准的一部分,广泛支持在不同的操作系统上,特别是对于文件描述符和套接字,它不涉及设备控制,仅用于操作文件描述符。
二.异步IO
fd = open(filename, O_RDWR | O_NONBLOCK);
三.设置超时
非阻塞接收数据
ssize_t NonBlockRecv(void* buf,size_t len) //非阻塞的接收数据{return Recv(buf,len,MSG_DONTWAIT); //MSG_DONTWAIT表示当前接收为非阻塞}
非阻塞发送数据
ssize_t NonBlockSend(void* buf,size_t len) //非阻塞的发送数据{if (len == 0) return 0;return Send(buf,len,MSG_DONTWAIT); //MSG_DONTWAIT表示当前发送为非阻塞}