#include <fcntl.h>
/** Returns true on success, or false if there was an error */
bool SetSocketBlockingEnabled(int fd, bool blocking)
{
if (fd < 0) return false;
#ifdef _WIN32
unsigned long mode = blocking ? 0 : 1;
return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? true : false;
#else
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) return false;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return (fcntl(fd, F_SETFL, flags) == 0) ? true : false;
#endif
}
1
你被误导了 fcntl() 并不总是可靠的 . 这是不真实的 .
要将套接字标记为非阻塞,代码就像下面这样简单:
// where socketfd is the socket you want to make non-blocking
int status = fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK);
if (status == -1){
perror("calling fcntl");
// handle the error. By the way, I've never seen fcntl fail in this way
}
// client side
int socketfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
// server side - see man page for accept4 under linux
int socketfd = accept4( ... , SOCK_NONBLOCK);
7 回答
我知道这是一个古老的问题,但对于google上的所有人来说,这里寻找有关如何处理阻塞和非阻塞套接字的信息,这是对如何处理套接字的I / O模式的不同方法的深入解释 - http://dwise1.net/pgm/sockets/blocking.html
快速摘要:
So Why do Sockets Block?
What are the Basic Programming Techniques for Dealing with Blocking Sockets?
Have a design that doesn't care about blocking
Using select
Using non-blocking sockets.
Using multithreading or multitasking
在C中将套接字设置为非阻塞的最佳方法是使用ioctl . 接受的套接字设置为非阻塞的示例如下:
"not always reliable"是什么意思?如果系统成功设置套接字非阻塞,则它将是非阻塞的 . 如果阻塞需要阻塞(例如,如果输出缓冲区已满并且您经常调用发送/写入),则套接字操作将返回
EWOULDBLOCK
.使用非阻塞调用时,This forum thread有一些好处 .
fcntl()一直对我来说可靠 . 在任何情况下,这是我用来启用/禁用套接字阻塞的函数:
你被误导了
fcntl()
并不总是可靠的 . 这是不真实的 .要将套接字标记为非阻塞,代码就像下面这样简单:
在Linux下,在内核> 2.6.27上,您还可以使用socket()和accept4()从一开始就创建非阻塞套接字 .
例如
它节省了一些工作,但不太便携,所以我倾向于用
fcntl()
设置它 .fcntl()
或ioctl()
用于设置文件流的属性 . 当您使用此函数使套接字无阻塞时,像accept()
,recv()
等函数本质上是阻塞的,将返回错误,errno
将设置为EWOULDBLOCK
. 您可以轮询文件描述符集以在套接字上轮询 .通常,使用
select(2)
,poll(2)
或系统上可用的某些其他系统调用,使用普通的 blocking IO 和 multiplexing 几个IO操作可以达到相同的效果 .有关可扩展IO多路复用方法的比较,请参见The C10K problem .