做多了windows,发现多select模式是那么的陌生,当想用心挖掘一下ACE::select的封装的时候,才发现自己几乎写不出一个完整的 select模式示例,这其实是我一直没有重视过这个东西,现在细细分析来,发现,它要比我以往在处理类似问题的时候处理的更为简单。
- WSAData wd;
- WSAStartup(MAKEWORD(2,2),&wd);
- SOCKET sock = socket(AF_INET,SOCK_STREAM,0);
- sockaddr_in saddr;
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
- saddr.sin_port = htons(2350);
- bind(sock,(SOCKADDR*)&saddr,sizeof(saddr));
- listen(sock,5);
-
- SOCKET sk2 = socket(AF_INET,SOCK_STREAM,0);
- sockaddr_in saddr2;
- saddr2.sin_family = AF_INET;
- saddr2.sin_addr.s_addr = inet_addr("127.0.0.1");
- saddr2.sin_port = htons(2340);
- bind(sk2,(SOCKADDR*)&saddr2,sizeof(saddr2));
- listen(sk2,5);
-
- fd_set rfd;
- fd_set bkfd;
-
-
- SOCKET sac = INVALID_SOCKET;
- SOCKET sac2 = INVALID_SOCKET;
-
- FD_ZERO(&bkfd);
- FD_SET(sock,&bkfd);
- FD_SET(sk2,&bkfd);
- while(true)
- {
- memcpy(&rfd,&bkfd,sizeof(bkfd));
- int sret = select(0,&rfd,NULL,NULL,NULL);
- cout<<"sret:"<<sret<<endl;
- if( ! (sret > 0) )
- {
- cout<<"lasterror:"<<WSAGetLastError()<<endl;
-
- }
- if (FD_ISSET(sock,&rfd))
- {
- closesocket(sac);
- int len = sizeof(saddr);
- sac = accept(sock,(SOCKADDR*)&saddr,&len);
- FD_SET(sac,&bkfd);
- }
- else if (FD_ISSET(sk2,&rfd))
- {
- closesocket(sac2);
- int len = sizeof(saddr2);
- sac2 = accept(sk2,(SOCKADDR*)&saddr2,&len);
- FD_SET(sac2,&bkfd);
- }
- else if (FD_ISSET(sac,&rfd))
- {
- char buf[1024];
- int len = recv(sac,buf,1024,0);
- if(!(len > 0))
- {
- closesocket((sac));
- cout<<"close a socket"<<endl;
- FD_CLR(sac,&bkfd);
- }
- else
- {
- buf[len] = 0;
- cout<<"recv:"<<buf<<endl;
- }
- }
- else if (FD_ISSET(sac2,&rfd))
- {
- char buf[1024];
- int len = recv(sac2,buf,1024,0);
- if (len <= 0)
- {
- closesocket(sac2);
- cout<<"close a socket"<<endl;
- FD_CLR(sac,&bkfd);
- }
- else
- {
- buf[len] = 0;
- cout<<"recv:"<<buf<<endl;
- }
- }
- }
- WSACleanup();
- return 0;
现在我感觉到,如果想做轻量级的多sock或者异步模式,select是个不错的选择。
(win2ks) |