关于线程中调用select的问题

ccpaishi 2007-05-29 10:51:58
DWORD WINAPI netProc(LPVOID pParam)
{
int i = 0;
PArmTheadParam montp;
montp = (PArmTheadParam)pParam;
int res;
char recvBuf[100];
while (!b_stopFlag)
{
for(i = 0;i < montp->GunNum ; i++)
{
fd_set fdRead;
timeval mWaitTime;

mWaitTime.tv_sec = 1;
mWaitTime.tv_usec = 0;
memset(recvBuf,0,100);
memset(Buf,0,250);

FD_ZERO(&fdRead);
FD_SET(montp->s[i],&fdRead);
res = select((montp->s[i])+1,&fdRead,NULL,NULL,&mWaitTime);
if(res > 0)
{
if(FD_ISSET(montp->s[i],&fdRead))
{
recv(montp->s[i],recvBuf,22,0);
GUNSTATE GunState;
memcpy(&GunState,recvBuf+17,5);
//如果任何一个模块有异常,则返回模块异常
if((GunState. mGS[0].MState== 0) || (GunState.mGS[1].MState == 0)|| (GunState.mGS[2].MState == 0) || (GunState.mGS[3].MState == 0))
{
// closesocket(montp->s[i]);
// WSACleanup();
COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
cpd.dwData = GUN_MSTATE_ERROR;
cpd.cbData = 4;
cpd.lpData = (PVOID)&(montp->beginAddr[i]);
SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);//消息处理函数
}

if(recvBuf[10] == 0x01)
{
COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
cpd.dwData = GUN_GATE_CHANGED;
cpd.cbData = 4;
cpd.lpData = (PVOID)&(montp->beginAddr[i]);

SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);
}
if(recvBuf[10] == 0x02)
{
int j ,k;
for(j = 0 ;j < 4 ; j++)
{
for(k = 0 ; k < 6;k++)
{
// memcpy(Buf+30*j+5*k,&(montp->beginAddr[i]),4);
Buf[30*j+5*k] = (char)((montp->beginAddr[i]) & 0xff);
Buf[30*j+5*k+1] = (char)(((montp->beginAddr[i])>>8)& 0xff);
Buf[30*j+5*k+2] = (char)(((montp->beginAddr[i])>>16)& 0xff);
Buf[30*j+5*k+3] = (char)(((montp->beginAddr[i])>>24)& 0xff);

Buf[30*j+5*(k+1)-1] = (GunState.mGS[j].GS >> k)& 1;
montp->beginAddr[i]++;
}
}
montp->beginAddr[i] = montp->beginAddr[i] - 24 ;

if(montp->recvHd != NULL)
{
COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
cpd.dwData = GUN_STATUS_CHANGED;
cpd.cbData = 120;
cpd.lpData = (PVOID)Buf;
SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);//消息处理函数
}
}
}
}
Sleep(100);
}
}
COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
cpd.dwData = MSG_COPYDATA_STOP;
cpd.cbData = 0;
cpd.lpData = NULL;
SendMessage(montp->recvHd,WM_COPYDATA,(WPARAM)(montp->threadHd),(LPARAM)&cpd);
b_threadRunning = FALSE;
CloseHandle(hThread);

for(i = 0;i < montp->GunNum;i++)
{
closesocket(montp->s[i]);
}
WSACleanup();
ExitThread(0);
return 0;
}



NETGUNCABDLL_API int NetStartMonitor(unsigned long *netIp, unsigned short netPort,int GunNum,unsigned long *beginAddr,HWND recvHd ,HANDLE *threadHd)
{
DWORD tId;
PArmTheadParam pMontp; // 设置传入参数

pMontp = new _ArmThreadParam;
pMontp->GunNum = GunNum;
pMontp->netPort = netPort;
pMontp->recvHd = recvHd;

int i;
for(i = 0;i < GunNum; i++)
{
pMontp->netIp[i] = netIp[i];
pMontp->beginAddr[i] = beginAddr[i];
}

WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2,2); //初始化socket链接的版本号
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return STARTUP_FAILED;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
return VERSION_FAILED;
}

SOCKET s[256];

for(i = 0;i < GunNum;i++)
{
if((s[i] = socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR) //生成SOCKET
{
closesocket(s[i]);
WSACleanup();
return CREATESOCKET_ERROR;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = netIp[i];
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(netPort);

if(connect(s[i],(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)) == SOCKET_ERROR) //连接socket
{
closesocket(s[i]);
WSACleanup();
return CONNECT_ERROR;
}
pMontp->s[i] = s[i];
}

*threadHd = CreateThread(NULL,0,netProc,(LPVOID)pMontp,CREATE_SUSPENDED,&tId); //线程挂起
if(*threadHd == NULL)
{
return CREATE_THREAD_FAILED;
}

pMontp->threadHd = *threadHd;
b_threadRunning = true;

ResumeThread(*threadHd); // 线程运行

delete pMontp;
return 0;
}


我这是一个线程中希望调用select判断是否有数据可读的情况,按照需要由于需要轮询多个socket,所以设置了超时,但是我始终不能接收到数据,希望高手指教一下,这个函数哪里除了问题。
...全文
394 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccpaishi 2007-06-05
  • 打赏
  • 举报
回复
谢谢了,问题已经解决了
yesry 2007-06-04
  • 打赏
  • 举报
回复
wzbhbb(灯火阑珊) 的方法可以同时盯着5个socket。理论上可以同时盯着64个。如果要轮训更多的,则把超时设成0:
mWaitTime.tv_sec = 0;
mWaitTime.tv_usec = 0;

但是这样又带来问题,所有的SOCKET轮训后如果立即又轮训,那么CPU是不是占用太多?如果超时不设成0,则轮训总汇带来等待。
CathySun118 2007-06-03
  • 打赏
  • 举报
回复
mWaitTime改长些试试
ccpaishi 2007-05-31
  • 打赏
  • 举报
回复
恩,这样我试过了,但是这样会是阻塞的效果啊,能起到轮询的作用吗
ccpaishi 2007-05-29
  • 打赏
  • 举报
回复
是啊,但是在这一段我已经连接上了,就是连接上了之后不能接受到可读的事件。
@@鹏~~~ 2007-05-29
  • 打赏
  • 举报
回复
首先,我看你的程序中有一段:
if(connect(s[i],(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)) == SOCKET_ERROR) //
{
closesocket(s[i]);
WSACleanup();
return CONNECT_ERROR;
}
那么连接中如果出现错误,那么线程函数就不会调用,你调试以下看看这里是否出现了问题
@@鹏~~~ 2007-05-29
  • 打赏
  • 举报
回复
试试这个:
while (true)
{
FD_SET SocketSet;
SocketSet.fd_count = 5;//这里是你的连接数
SocketSet.fd_array[1,2,3,4,5] = yousocket;//5个
int Ret = select(0, &SocketSet,NULL,NULL,NULL);
......
FD_ISSET(yousocket, &SocketSet);
.....
}

18,356

社区成员

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

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