在 Linux 和 Windows 系統中,都可以將 socket 設置為非阻塞模式。
Linux平臺
- 在 Linux 系統中,可以使用?
fcntl
?函數來設置 socket 為非阻塞模式。例如:
int flags = fcntl(socket_fd, F_GETFL, 0);
fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
- 此外,Linux 還提供了一個?
accept4
?函數,可以直接將返回的 socket 設置為非阻塞模式:
int client_fd = accept4(server_fd, (struct sockaddr *)&client_addr, &client_addr_len, SOCK_NONBLOCK);
- 設置阻塞模式,默認阻塞模式不用單獨設置
int flags = fcntl(socket_fd, F_GETFL, 0);
fcntl(socket_fd, F_SETFL, flags | ~O_NONBLOCK);
Windows平臺
- 在 Windows 系統中,可以使用?
ioctlsocket
?函數來設置 socket 為非阻塞模式。例如:
u_long mode = 1;
ioctlsocket(socket_fd, FIONBIO, &mode);
- 設置阻塞模式
u_long mode = 0;
ioctlsocket(socket_fd, FIONBIO, &mode);
封窗兩個函數方便調用
設置非阻塞模式
void SetNonBlocking(SOCKET sockfd)
設置阻塞模式
void SetBlocking(SOCKET sockfd)
#ifdef __GNUC__
#define SOCKET int
#elif defined(_WIN32)
#endifvoid SetNonBlocking(SOCKET sockfd){
#ifdef _WIN32unsigned long flag = 1;if(ioctlsocket(sockfd, FIONBIO, &flag) == SOCKET_ERROR){
#elseint cflags = fcntl(sockfd, F_GETFL, 0); if(fcntl(sockfd, F_SETFL, cflags | O_NONBLOCK) == -1){
#endifstd::cerr << "ioctlsocket or fcntl set non blocking error" << std::endl;exit(-1);}
}void SetBlocking(SOCKET fd){
#ifdef _WIN32unsigned long flag = 0;if(ioctlsocket(sockfd, FIONBIO, &flag) == SOCKET_ERROR){
#elseint cflags = fcntl(sockfd, F_GETFL, 0); if(fcntl(sockfd, F_SETFL, cflags & ~O_NONBLOCK) == -1){
#endifstd::cerr << "ioctlsocket or fcntl set non blocking error" << std::endl;exit(-1);}
}