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似乎没有这样事件定义。
版权声明:本文为博主原创文章,未经博主允许不得转载。