MFC_IO模型_select

今天发现了socket的一点:当A客户端连接到B服务器的时候,A成功连接并且发送给B服务器的时候,然后A客户端在关闭socket,而B服务器还是能收到客户端第一次发送的数据,这应该是脏数据了,是用的select模型做的,不知道是不是和select模型有关系,大家自己测试吧

 

 

1.定义一个   fd_set         fdread;//结构

2.定一个,这个用来超时等待的设置   struct timeval tv = {0, 200};//超时时间 SELECT模型中用到的这里是200毫秒  ,第一个参数为秒,第二个为毫秒,任选一个

3.重置,FD_ZERO(&fdread);//清空fd_set结构     如果 不重新设置的话,那么每次都是监听的那几个socket,这就不符合我们的项目,比如局域网聊天吧,用户每次加入进来,则需要让咱们的select去监听他,所以得先清空,然后加入咱们的list集合的socket

4.加入FD_SET(pDlg->CliSocketArr[i].cliensocket,&fdread);,把需要监听的socket对象加入到fd_set集合中

5.开始监听:ret = select(0, &fdread, NULL, NULL, &tv);//,第一个参数是为了兼容UNIX,第二个参数为需要监听读,第三个为监听写,第三个为例外数据,第四个参数为超时等待,

            这个select函数有什么作用呢?这个函数的作用就是当 socket,也就是我们的肉鸡,给我们发送数据来的时候,你不可能一个肉鸡对应一个线程吧?那不卡死你,

            所以得需要用到我们的select异步模型,select的函数的作用就是,当socket中有数据读的时候,他就会返回,返回的参数为:有几个需要读,也就是系统告诉我们,你需要读几个socket

6.读socket中的数据

 

for (i = 0; i < 你的肉鸡集合; i++)
{
if (FD_ISSET(你的肉鸡集合的socket, &fdread))//判断是否有数据需要读取,判断这个socket是否有数据
{

//...如果有数据读取,则读取

ret = recv(pDlg->CliSocketArr[i].cliensocket, szMessage,sizeof(szMessage), 0);//读入缓冲区

//..读入的内容自己处理,

if (ret == -1 || ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))//如果是-1或者错误了还读个P啊,直接关闭socket
{
// Client socket closed
//客户端关闭
closesocket(pDlg->CliSocketArr[i].cliensocket);//关闭这个套接字
if (pDlg->TotalConn==1)
{
pDlg->TotalConn--;//如果只有一个客户端
}else
{
if(i==pDlg->TotalConn-1){//判断是否是最后一个
//如果是最后一个的话,直接-1
pDlg->TotalConn--;
}else{//说明不是最后一个,则把后面一个提升上来
pDlg->CliSocketArr[i]=pDlg->CliSocketArr[i+1];
pDlg->TotalConn--;
//这时候需要i--,
//如果i不减的话,那么提升上来的这个他就遍历不到了
i--;
}
}
}

}

}

posted @ 2013-08-09 01:59  宝贝,我永远都在  阅读(919)  评论(0)    收藏  举报