#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;
}