做了一个客户端程序连服务器,在线程里面用WSAEventSelect来选择网络事件,实际运行过程中发现客户端对服务器的指令有时根本没反映,(不是每次,只是有时候,但出现频率还是比较高的),我用网络抓包,发现服务器信息已经发到了客户端,但是却没有触发已定义的网络事件了,不知道为什么?请各位帮忙,相关代码如下(省去了具体的数据处理部分),谢谢!!
     WSAEVENT Event[1];
WSANETWORKEVENTS NetWorkEvents;
WSAEVENT NewEvent = WSACreateEvent();     int rc = WSAEventSelect(Port->m_CSocket, NewEvent, _READ|FD_WRITE|FD_ACCEPT|FD_CLOSE|FD_CONNECT);
Port->Socket[EventTotal] = Port->m_CSocket;
Event[EventTotal] = NewEvent;
EventTotal++; while(TRUE)
{
Index = WSAWaitForMultipleEvents(EventTotal,Event,false,1000,false);
Index = Index - WSA_WAIT_EVENT_0; if((WSA_WAIT_FAILED == Index) || (WSA_WAIT_TIMEOUT == Index))
{
m_uErr = WSAGetLastError();
continue;
}
//判断网络事件
WSAResetEvent(Event);
Index = Index - WSA_WAIT_EVENT_0;
iResult = WSAEnumNetworkEvents(Port->Socket[0],Even[0],&NetWorkEvents);

if(iResult != 0)
{
m_uErr = WSAGetLastError();
continue;
} //处理网络事件
if(NetWorkEvents.lNetworkEvents & FD_ACCEPT)
{
AfxMessageBox("FD_ACCEPT");
}
//判断是否连接成功
else if(NetWorkEvents.lNetworkEvents & FD_CONNECT)
{
if(NetWorkEvents.iErrorCode[FD_CONNECT_BIT] != 0)
{
AfxMessageBox("FD_CONNECT_Error");
break;
}
//AfxMessageBox("连接成功!"); }
//接受信息
else if(NetWorkEvents.lNetworkEvents & FD_READ)
{
//具体的数据处理
}

else if(NetWorkEvents.lNetworkEvents & FD_WRITE)
{
if(NetWorkEvents.iErrorCode[FD_WRITE_BIT] != 0)
{
AfxMessageBox("FD_WRITE_Error");
break;
}
SetEvent(Port->g_eventSendOk);
}
else if(NetWorkEvents.lNetworkEvents & FD_CLOSE)
{
if(NetWorkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
{
// AfxMessageBox("FD_CLOSE_Error");
//break;
}
}
         }

解决方案 »

  1.   

    问过了一个高手,他说问题可以出在两方面,一个是WSAResetEvent(Event)调用时机太早,另外一个可能说是如果触发了一个fd_read事件后,正在处理过程中,另一个新的网络事件又被触发了,新事件和旧事件有冲突,所以导致结果不可知。但是我现在搞不清楚实际是不是这个原因。请各位帮忙赐教,谢谢
      

  2.   

    Index = WSAWaitForMultipleEvents(EventTotal,Event,false,1000,false);
    Index = Index - WSA_WAIT_EVENT_0;if((WSA_WAIT_FAILED == Index) || (WSA_WAIT_TIMEOUT == Index))
    {
    m_uErr = WSAGetLastError();
    continue;
    }
    //////////////////////////////////////////////////////Index = WSAWaitForMultipleEvents(EventTotal,Event,false,1000,false);
    if((WSA_WAIT_FAILED == Index) || (WSA_WAIT_TIMEOUT == Index))
    {
    m_uErr = WSAGetLastError();
    continue;
    }Index = Index - WSA_WAIT_EVENT_0;
      

  3.   

    谢谢飘人,我按您的办法修改后,再测试这个程序,同时再问您和各位一个问题:按我的理解,使用了WSAEnumNetworkEvents函数,就已经起到了把event重新设置的作用,是否就不需要在调用
    WSAResetEvent(Event)了??谢谢