标签:
int select(
my_socket();
my_bind(port);
my_listen();
//PostMessage(h_hand,WM_USER_THREADEND,0,0);
//select模型处理过程
//(1).初始化套接字集合fdSocket.添加监听套接字句柄到这个集合
FD_ZERO(&fdSocket);
FD_SET(sSock,&fdSocket);
while (1)
{
//(2.)将fdSocket集合的一个拷贝fdRead传递给select函数
//当有时间发生时,select函数一处fdRead集合中没有未决IO操作的套接字句柄,然后返回。
fd_set fdRead = fdSocket;
int nRet = select(0,&fdRead,NULL,NULL,NULL); //timeout参数控制select()完成的时间。若timeout参数为空指针,则select()将一直阻塞
//到有一个描述字满足条件。否则的话,timeout指向一个timeval结构,其中指定了select()
//调用在返回前等待多长时间
//fdwrite 1. 接成功的套接字 在第一次建立连接时,C/S端都会触发一个FD_WRITE事件
//2, 触发的前提是 缓冲区要先被充满然后随着数据的发送又出现可用空间
if(nRet>0)
{
//(3)通过原来的fdSocket集合与select处理后的fdRead集合比较
//确定哪些套接字有未决io,并进一步处理这些io
for(int i=0;i<(int)fdSocket.fd_count;i++)
{
if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
{
if(fdSocket.fd_array[i] == sSock) //(1)监听套接字收到新连接,有新的链接
{
if(fdSocket.fd_count<FD_SETSIZE) //判断集合满了吗?
{
int socke_len = sizeof(remoteAddr);
//4.accept
SOCKET cSock = accept(sSock,(SOCKADDR*)&remoteAddr,&socke_len);
if(cSock == INVALID_SOCKET)
{
AfxMessageBox("accept failed!\n");
printf("accept failed!\n");
continue;
}
FD_SET(cSock,&fdSocket);
//printf("接收到一个连接请求!:%s\r\n",inet_ntoa(remoteAddr.sin_addr) );
//printf("当前连接到服务器的客户端有 %d 个\n",fdSocket.fd_count+1);
socket_id = cSock*(-1);
PostMessage(h_hand,WM_USER_THREADEND,0,0);
}
else
{
AfxMessageBox("too much connections !\n");
printf("too much connections \n");
continue;
}
}
else
{
int nRecv = recv(fdSocket.fd_array[i],readText,sizeof(readText),0);
socket_id = fdSocket.fd_array[i];
if(nRecv>0) //(2)可读
{
readText[nRecv] = ‘\0‘;
//HWND g_WindowHandle=((CDialog *)AfxGetMainWnd())->GetSafeHwnd();
PostMessage(h_hand,WM_USER_THREADEND,0,0);
}
else //(3)连接关闭,重启或中断
{
closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i],&fdSocket);
someone_out = TRUE;
PostMessage(h_hand,WM_USER_THREADEND,0,0);
}
}
}
}
}
else
{
AfxMessageBox("failed select()]n");
printf("failed select()]n");
break;
}
}
以上只是我在项目中使用的部分代码,最开始的my_socket,my_bind,my_listen都是自己对socket,bind,listen自己重新做的封装
标签:
原文地址:http://www.cnblogs.com/marktubu/p/4698827.html