我建了个select模式 但是Client端的可读却一直进不去 大虾看看

kooko1986 2010-08-27 05:09:25
网络通讯,建了个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);


大家帮忙看看:) 谢谢
...全文
133 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
xgPaul 2010-09-06
  • 打赏
  • 举报
回复
下面是一个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;
}
jyh_baoding 2010-09-06
  • 打赏
  • 举报
回复
看看SELECT的用法。好象和你的方法有出入
Eleven 2010-08-31
  • 打赏
  • 举报
回复
你的select模型使用的有些问题,放在一个while中,在里面select()
kooko1986 2010-08-27
  • 打赏
  • 举报
回复
奇怪 我selece2次,把可读和可写分开程序就正常了,放一起就不行,
kooko1986 2010-08-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wade008 的回复:]
这段为什么放在Timer里面?
[/Quote]一个函数里面的,那个函数在OnTimer里面每5秒执行一次
wade008 2010-08-27
  • 打赏
  • 举报
回复
这段为什么放在Timer里面?

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧