程序流程很简单,监听,然后得到一个连接以后,利用overlapped跟一个事件对象,首先调用WSARecv接收数据,然后再用WSASend发回一个"ECHO"字符串,都完成以后关闭连接。
现在碰到这么一个很奇怪的问题,如果把下面代码里面的注释部分做成一个独立的函数来调用的话,WSASend以后就等不到相应的事件对象完成,如果不做成独立函数,就把DispatchMsg调用注释掉,然后所有代码放那边的话又正常,这到底是什么原因?
下面是代码,环境是VS2005+WINXP SP3struct SOCKOBJ
{
SOCKET sock;
int    status;
char*  pBuf;
};typedef stdext::hash_map<WSAEVENT,SOCKOBJ *> event_map;void DispatchMsg(WSAEVENT hEvent,event_map & sockmap);int _tmain(int argc, _TCHAR* argv[])
{
event_map sockmap;
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
SOCKET sockListener = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN addrListen,addrconn;
int len = sizeof (addrconn);
memset(&addrListen,0,sizeof (addrListen));
addrListen.sin_family = AF_INET;
addrListen.sin_port = htons(8888);
addrListen.sin_addr.s_addr = htonl(ADDR_ANY);
bind(sockListener,(sockaddr *)&addrListen,sizeof (addrListen));
listen(sockListener,5);
SOCKOBJ *pObj = new SOCKOBJ;
pObj->sock = accept(sockListener,(sockaddr *)&addrconn,&len);
pObj->status = 0;
pObj->pBuf = new char[255];
WSAEVENT hEvent = WSACreateEvent();
sockmap[hEvent] = pObj;
OVERLAPPED overlapped;
memset(&overlapped,0,sizeof (overlapped));
overlapped.hEvent = hEvent;
WSABUF recvBuf;
recvBuf.buf = pObj->pBuf;
recvBuf.len = 255;
DWORD dwRecv = 0;
DWORD dwFlag = 0;
WSARecv(pObj->sock,&recvBuf,1,&dwRecv,&dwFlag,&overlapped,NULL);
WSAEVENT event_snap[WSA_MAXIMUM_WAIT_EVENTS];
while (sockmap.size() != 0)
{
int nEvents = 0;
event_map::iterator ite;
for (ite = sockmap.begin();ite != sockmap.end();ite++)
event_snap[nEvents++] = (*ite).first;
int nIndex = WSAWaitForMultipleEvents(nEvents,event_snap,FALSE,WSA_INFINITE,FALSE);
if (nIndex == WSA_WAIT_FAILED)
{
cout<<"Error"<<endl;
break;
}
else
{
nIndex -= WSA_WAIT_EVENT_0;
WSAResetEvent(event_snap[nIndex]);
DispatchMsg(event_snap[nIndex],sockmap);

                        //把下面的注释全部取消掉,然后注释掉上面的DispatchMsg调用运行正常
//  SOCKOBJ *curObj = sockmap[event_snap[nIndex]];
//  switch (curObj->status)
//  {
//  case 0:
//  {
//  cout<<"Recv msg: "<<curObj->pBuf<<endl;
//  memset(curObj->pBuf,0,255);
//  strcpy(curObj->pBuf,"echo");
//  WSABUF sendBuf;
//  sendBuf.buf = curObj->pBuf;
//  sendBuf.len = 255;
//  OVERLAPPED olsend;
//  memset(&olsend,0,sizeof (olsend));
//  olsend.hEvent = event_snap[nIndex];
//  DWORD dwRecv = 0;
//  DWORD dwFlag = 0;
//  curObj->status = 1;
//  WSASend(curObj->sock,&sendBuf,1,&dwRecv,dwFlag,&olsend,NULL);
//  }
//  break;
//  case 1:
//  {
//  cout<<curObj->pBuf<<endl;
//  sockmap.erase(sockmap.find(hEvent));
//  closesocket(curObj->sock);
//  WSACloseEvent(event_snap[nIndex]);
//  delete[] curObj->pBuf;
//  delete curObj;
//  break;
//  }
//  }
}
}
WSACleanup();
return 0;
}void DispatchMsg(WSAEVENT hEvent,event_map & sockmap)
{
SOCKOBJ *curObj = sockmap[hEvent];
switch (curObj->status)
{
case 0:
{
cout<<"Recv msg: "<<curObj->pBuf<<endl;
memset(curObj->pBuf,0,255);
strcpy(curObj->pBuf,"echo");
WSABUF sendBuf;
sendBuf.buf = curObj->pBuf;
sendBuf.len = 255;
OVERLAPPED olsend;
memset(&olsend,0,sizeof (olsend));
olsend.hEvent = hEvent;
DWORD dwRecv = 0;
DWORD dwFlag = 0;
curObj->status = 1;
WSASend(curObj->sock,&sendBuf,1,&dwRecv,dwFlag,&olsend,NULL);
}
break;
case 1:
{
cout<<curObj->pBuf<<endl;
sockmap.erase(sockmap.find(hEvent));
closesocket(curObj->sock);
WSACloseEvent(hEvent);
delete[] curObj->pBuf;
delete curObj;
break;
}
}
}