做多了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; // read fd
fd_set bkfd; // fdbake
// fd_set wfd; // write fd
// fd_set etfd; // except fd
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;
//break;
}
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 ;
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; // read fd
fd_set bkfd; // fdbake
// fd_set wfd; // write fd
// fd_set etfd; // except fd
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;
//break;
}
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是个不错的选择。