select模型实例

#include <WINSOCK2.H>
#include
<iostream>
#pragma comment(lib,"ws2_32")

int main()
{
using namespace std;
WSADATA wsaData;
WORD sockVersion
=MAKEWORD(2,2);
if (WSAStartup(sockVersion,&wsaData)!=0)
{
cout
<<"套接字库加载失败!";
exit(
0);
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
cout
<<"套接字库加载失败!";
exit(
0);
}
USHORT nPort
=4567;
SOCKET sListen
=socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addrin;
addrin.sin_addr.S_un.S_addr
=INADDR_ANY;
addrin.sin_family
=AF_INET;
addrin.sin_port
=htons(nPort);

if (SOCKET_ERROR==bind(sListen,(sockaddr*)&addrin,sizeof(sockaddr)))
{
cout
<<"绑定失败!\n";
return -1;
}
//进入监听模式
if (SOCKET_ERROR==listen(sListen,5))
{
cout
<<"监听失败!\n";
return -1;
}

//select模型处理过程
fd_set fdSocket;
FD_ZERO(
&fdSocket);
FD_SET(sListen,
&fdSocket);
while (true)
{
//将fdSocket集合的一个拷贝fdRead传递给Select函数
//当有事件发生时,Select函数移除fdRead集合中没有未决I/O操作的套接字句柄,然后返回
fd_set fdRead=fdSocket;
int nRet=select(0,&fdRead,NULL,NULL,NULL); //等待时间设为NULL,让它知道有时间发生时候才返回
if (nRet>0)
{
//通过原来fdSocket集合与Select处理过的fdRead集合比较,确定有哪些套接字有未决I/O,并进一步处理
for (int i=0;i<(int)fdSocket.fd_count;i++)
{
if (FD_ISSET(fdSocket.fd_array[i],&fdRead))
{
if (sListen==fdSocket.fd_array[i]) //监听套接字接收到新连接
{
if (fdSocket.fd_count<FD_SETSIZE) //小于fs_set结构的套接字最大数量
{
sockaddr_in addrRemote;
int nAddrlen=sizeof(addrRemote);
SOCKET NewSocket
=accept(sListen,(sockaddr*)&addrRemote,&nAddrlen);
FD_SET(NewSocket,
&fdSocket);
cout
<<"接收到"<<inet_ntoa(addrRemote.sin_addr)<<"的连接\n";
}
else
{
cout
<<"连接数已经到达顶限\n";
continue;
}
}
else
{
char szText[256];
int nRecv=recv(fdSocket.fd_array[i],szText,256,0);
if (nRecv>0) //数据可读
{
szText[nRecv]
='\0';
cout
<<"接收到数据:"<<szText<<endl;
}
else //连接关闭,重启或者中断
{
closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],
&fdSocket);
}
}
}
}
}
else
{
cout
<<"Select执行失败!\n";
break;
}
}
return 0;
}
posted @ 2011-07-08 09:09  likebeta  阅读(1249)  评论(0编辑  收藏  举报