windows平台下异步IO可以通过WSAEventSelcet来实现IO读写操作的异步通知,UNIX下也有一个类型的SIGIO信号来实现IO异步通知机制。为了验证该功能,自己做了一个 demo,发帖保存一下。
1.首先初始化一个socket(当然也可以用其它的文件描述符);将这个文件描述符设置成异步非阻塞;初始化一个SIGIO信号的处理函数
struct sockaddr_in serv_addr1;
s_sockListen = socket(AF_INET,SOCK_STREAM,0);
serv_addr1.sin_family = AF_INET;
serv_addr1.sin_port = htons(5999);
serv_addr1.sin_addr.s_addr = INADDR_ANY;
//捆绑SIGIO信号的处理
struct sigaction sigio_action;
memset(&sigio_action, 0, sizeof(sigio_action));
sigio_action.sa_flags = 0;
sigio_action.sa_handler = do_sigio;
sigaction(SIGIO, &sigio_action, NULL);
//将文件描述符和本进程进行 捆绑
fcntl(s_sockListen,F_SETOWN,getpid());
int nIOflag = fcntl(s_sockListen,F_GETFL,0);
nIOflag = nIOflag|O_ASYNC|O_NONBLOCK;
//设置s_sockListen为异步非阻塞
fcntl(s_sockListen,F_SETFL,nIOflag);
if(bind(s_sockListen, (struct sockaddr *) &serv_addr1, sizeof(serv_addr1))<0)
THROW_EXCEPTION(LISTEN_SOCK_FAILE,errno,strerror(errno));
if(listen(s_sockListen, 0)<0)
THROW_EXCEPTION(BIND_SOCK_FAILE,errno,strerror(errno));
2.定义信号处理函数
void do_sigio(int sig)
{
int sockClient = -1;
socklen_t nCliSockLen;
struct sockaddr_in cli_addr;
char strPipeBuff[100]={0};
try
{
sockClient = accept(s_sockListen, (struct sockaddr *) &cli_addr, &nCliSockLen);
if (sockClient==-1) THROW_EXCEPTION(ACCT_SOCK_FAILE,errno,strerror(errno));
int n = read(sockClient,strPipeBuff,sizeof(strPipeBuff));
if(n==-1) THROW_EXCEPTION(RECV_SOCK_FAILE,errno,strerror(errno));
close(sockClient);
数据处理............
}
catch(WAMException &ex)
{
return;
}
}
总结:windows平台下的WSAEventselect模型可以精确定位到,读写,连接,断开等事件,Unix平台下除了epoll似乎没有这样事件定义。