网络通讯,建了个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);
大家帮忙看看:) 谢谢

解决方案 »

  1.   

    一个函数里面的,那个函数在OnTimer里面每5秒执行一次
      

  2.   

    奇怪 我selece2次,把可读和可写分开程序就正常了,放一起就不行,
      

  3.   

    你的select模型使用的有些问题,放在一个while中,在里面select()
      

  4.   

    看看SELECT的用法。好象和你的方法有出入
      

  5.   

    下面是一个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;
    }