几个结构及函数原型:
int select( int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout );
typedef struct fd_set { u_int fd_count; // how many are SET? SOCKET fd_array[FD_SETSIZE]; // an array of SOCKETs } fd_set;struct timeval { long tv_sec; // seconds long tv_usec; // and microseconds };
#include "stdafx.h"
#include <stdio.h>
#include <InitSock.h>
CInitSock theSock;//链接到winsock库的载入及释放(资源分配即初始化)
int main(int argc, char* argv[])
{
USHORT nPort=4567;
//创建监听套接字
SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(nPort);
sin.sin_addr.S_un.S_addr=INADDR_ANY;
//绑定套接字到本地机器
if (::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("failed bind()/n");
return -1;
}
//进入监听模式
::listen(sListen,5);
//select模型处理过程
//1. 初始化一个套接字集合fdSocket,添加监听套接字句柄到这个集合
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(sListen,&fdSocket);
while (true)
{
//2) 将fdSocket的一个拷贝fdRead传递给select函数
//当有事件发生时,select函数移出fdRead集合中没有未决io操作的套接字句柄,返回
fd_set fdRead=fdSocket;
int nRet=::select(NULL,&fdRead,NULL,NULL,NULL);
// printf("hello/n");
if (nRet>0)
{
//3)比较fdSocket和fdRead,确定未决io;
for (int i=0;i<(int)fdSocket.fd_count;i++)
{
// printf("%d",(int)fdSocket.fd_count);
if (FD_ISSET(fdSocket.fd_array[i],&fdRead))
{
if (fdSocket.fd_array[i]==sListen)//监听套接字接收新连接
{
if (fdSocket.fd_count<FD_SETSIZE)
{
sockaddr_in addrRemote;
int nAddrLen=sizeof(addrRemote);
SOCKET sNew=::accept(sListen,(sockaddr*)&addrRemote,&nAddrLen);
FD_SET(sNew,&fdSocket);
printf("接收到连接(%s)/n",::inet_ntoa(addrRemote.sin_addr));
}
else
{
printf("too much connections!/n");
continue;
}
}
else
{
char szText[256];
int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
if (nRecv>0)//可读
{
szText[nRecv]='/0';
printf("接收到数据:%s",szText);
}
else //关闭连接,重启,中断
{
::closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],&fdSocket);
}
}
}
}
}
else
{
printf("failed select()!/n");
break;
}
}
return 0;
}