服务器端:
DWORD WINAPI CDisComSrvDlg::RecBusyOrNot(LPVOID lpParameter)
{
CDisComSrvDlg* pServe = (CDisComSrvDlg*)lpParameter;
SOCKET sListen = pServe->GetSockSrv();
FD_SET allSockfd; //服务器所有套接字结合
FD_ZERO(&allSockfd); //清空集合
FD_SET (sListen, &allSockfd); //将监听套接字加入该集合
FD_SET readfd; //定义满足可读套接字
FD_SET writefd; //定义满足可写套接字
while (pServe->IsConnenting()) //服务器运行
{
FD_ZERO(&readfd); //清空
FD_ZERO(&writefd);
readfd = allSockfd; //赋值
writefd = allSockfd;
//更新界面
pServe->ShowClientNumberInfor(allSockfd.fd_count);
//无限期等待套接字满足条件
int nRet = select(0, &readfd, &writefd, NULL, NULL);
if (nRet > 0)
{
//遍历所有套接字集合
for (int i = 0; i < allSockfd.fd_count; i++)
{
//存在可读的套接字
if (FD_ISSET(allSockfd.fd_array[i], &readfd))
{
//连接服务器请求的套接字
if (allSockfd.fd_array[i] == sListen)
{
SOCKADDR_IN addrClient;
int naddrLen = sizeof(addrClient);
SOCKET sClient = accept(sListen, (sockaddr*)&addrClient, &naddrLen);
//加入套接字
FD_SET(sClient, &allSockfd);
pServe->ShowClientNumberInfor(allSockfd.fd_count);
//处理
pServe->EstiClientState(addrClient);
pServe->AllotWork(sClient, addrClient);
}
else //接收客户端的数据
{
SOCKET sRecv = allSockfd.fd_array[i]; //获取套接字
BOOL nRet = pServe->ReadClientData(sRecv);
if (nRet == FALSE) //失败
{
FD_CLR(allSockfd.fd_array[i], &allSockfd); //清除
pServe->ShowClientNumberInfor(allSockfd.fd_count);
}
}
}//if
//可写的套接字
if (FD_ISSET(allSockfd.fd_array[i], &writefd))
{
//已处理
}
}
}
Sleep(THREAD_SLEEP);
}
return 0;
}
客户端代码:
DWORD WINAPI CEdisComClientDlg::RecvAndSend(LPVOID lpParameter)
{
CEdisComClientDlg* pClient = (CEdisComClientDlg*)lpParameter;
SOCKET sClient = pClient->GetClientSock();
FD_SET writefd;
FD_SET readfd;
while (pClient->isConning()) //连接正常
{
FD_ZERO(&writefd);
FD_ZERO(&readfd);
FD_SET(pClient->GetClientSock(), &readfd); //添加到可读
FD_SET(pClient->GetClientSock(), &writefd); //添加到可写
int reVal;
reVal = select(0, &readfd, &writefd, NULL, NULL); //等待满足的套接字
if (reVal == SOCKET_ERROR)
{
pClient->MessageBox(_T("select错误"));
return 0;
}
else if (reVal > 0)
{
if (FD_ISSET(pClient->GetClientSock(), &writefd)) //满足可写的套接字
{
//已处理
}
else if (FD_ISSET(pClient->GetClientSock(), &readfd)) //满足可读的套接字
{
pClient->ReadSrvData(pClient->GetClientSock());
}
}
}
return 0;
}
在服务器端,首先服务器侦听,当有客户端请求连接时,就新建一个sClient,用来accept客户端。然后我直接用这个sClient发送命令包给客户端,发送是可以成功的。但是我的理解是此时客户端应该有一个可读的套接字,即
else if (FD_ISSET(pClient->GetClientSock(), &readfd)) //满足可读的套接字
{
pClient->ReadSrvData(pClient->GetClientSock());
}
应该执行。但是当我启动服务器,调试客户端时,为什么没有被执行呢?
应当怎么样使用select模型