我建了个select模式 但是Client端的可读却一直进不去 大虾看看
网络通讯,建了个select模型,调试后,Server端可以正常运行,读取字符串,发送字符串。但是Client端的话只能发送,不能读取。一直没有可读事件,
下面这个是我Client端的通讯的代码,是哪里出问题了吗?这段代码是在OnTimer里面每过5秒运行一次的。
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(7050);
sa.sin_addr.s_addr = inet_addr(strTempIpSel);
char m_strSendString[100];
strcpy(m_strSendString,"startchecktime");
struct timeval tv;
int ret;
fd_set wset,rset,eset;
sockSend = socket(AF_INET,SOCK_STREAM, 0);
connect(sockSend,(struct sockaddr *)&sa,sizeof(sa));
tv.tv_sec = 0;
tv.tv_usec = 5000;
FD_ZERO(&rset);
FD_SET(sockSend,&rset);
FD_ZERO(&wset);
FD_SET(sockSend,&wset);
FD_ZERO(&eset);
FD_SET(sockSend,&eset);
ret = select(sockSend+1,&rset,&wset,&eset,&tv);
if (ret < 0)
{
DWORD dwError = WSAGetLastError();
TRACE("select error \n");
closesocket(sockSend);
return;
//break;
}
if (ret == 0)
{
TRACE("超时,继续等待\n");
return;
//continue;
}
if (FD_ISSET(sockSend,&wset))
{
ret = send(sockSend,m_strSendString,strlen(m_strSendString),0);
if (ret < 0)
{
printf("send keep alive error\n");
closesocket(sockSend);
return;
//break;
}
Sleep(6000);
TRACE("可写结束\n");
}
TRACE("可写结束2\n");
if (FD_ISSET(sockSend,&rset))
{
TRACE("可读里面\n");
char buf[100];
ret = recv(sockSend,buf,100,0);
if (ret < 0)
{
closesocket(sockSend);
return;
}
buf[ret] = '\0';
CDVOCLIENTTIMEDlg *m_tempWnd = (CDVOCLIENTTIMEDlg *)AfxGetMainWnd();
strcpy(m_tempWnd->strLocalTime,buf);
m_tempWnd->SetSystemTimeWithServer();
TRACE("可读结束\n");
}
closesocket(sockSend);
大家帮忙看看:) 谢谢
[最优解释]
下面是一个select模型的服务器,楼主可以看一下
#include "../common/initsock.h"
#include <stdio.h>
CInitSock theSock;// 初始化Winsock库
int main()
{
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集合中没有未决I/O操作的套节字句柄,然后返回。
fd_set fdRead = fdSocket;
int nRet = ::select(0, &fdRead, NULL, NULL, NULL);
if(nRet > 0)
{
// 3)通过将原来fdSocket集合与select处理过的fdRead集合比较,
// 确定都有哪些套节字有未决I/O,并进一步处理这些I/O。
for(int i=0; i<(int)fdSocket.fd_count; i++)
{
if(FD_ISSET(fdSocket.fd_array[i], &fdRead))
{
if(fdSocket.fd_array[i] == sListen)// (1)监听套节字接收到新连接
{
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)// (2)可读
{
szText[nRecv] = '\0';
printf("接收到数据:%s \n", szText);
}
else// (3)连接关闭、重启或者中断
{
::closesocket(fdSocket.fd_array[i]);
FD_CLR(fdSocket.fd_array[i], &fdSocket);
}
}
}
}
}
else
{
printf(" Failed select() \n");
break;
}
}
return 0;
}