关于winsock程序中的服务器端不停产生FD_READ事件导致死循环问题.
1.建立一个面向连接的服务器程序,从WSASetup()->Socket()->bind()->listen()->后,加入:
WSAAsyncSelect(server,GetSafeHwnd(),WM_SOCKET_ACCECPT,FD_ACCEPT);
2.添加WM_SOCKET_ACCECPT的消息处理函数,调用accept()之后添加:
WSAAsyncSelect(client,GetSafeHwnd(),WM_SOCKET_MSG,FD_READ|FD_WRITE|FD_CLOSE);
3.添加WM_SOCKET_MSG的消息处理函数,如下:
CString sMSG;
char rbuf[50];
memset(rbuf,0,sizeof(rbuf));
int msg = lParam & 0x0000FFFF;
int rcnt=0;
switch(msg)
{
case FD_READ:// 接收数据
if((rcnt=recv(client,rbuf,strlen(rbuf),0))==SOCKET_ERROR )
{
CString sMSG;
sMSG.Format("socket接收失败,错误代码=%d",WSAGetLastError());
AfxMessageBox(sMSG);
}
else
{
if(rcnt>0)
{
rbuf[rcnt]='\0';
CString sMSG;
sMSG="接收到的消息是 : "+CString(rbuf);
//AfxMessageBox(sMSG);
m_ListBox.AddString(sMSG);
memset(rbuf,0,sizeof(rbuf));
WSAAsyncSelect(client,GetSafeHwnd(),0,0);}
}
break;
case FD_WRITE://发送数据
break;
case FD_CLOSE://关闭连接
m_ListBox.AddString("客户端关闭");
closesocket(client);
WSAAsyncSelect(client,GetSafeHwnd(),0,0);
break;
}现在出现的问题是,一旦客户端发送一次数据,服务器端没完没了的产生FD_READ事件,导致程序出现死循环.反复调用case FD_READ:后的代码.

解决方案 »

  1.   

    我觉得没必要再WSAAsyncSelect(client,GetSafeHwnd(),0,0)了吧
      

  2.   

    反复调用case FD_READ:后的代码.是if里的呢?还是else里面的?????
      

  3.   

    (rcnt=recv(client,rbuf,strlen(rbuf),0))==SOCKET_ERROR老大,你的缓冲为0~
      

  4.   

    原来去掉其中的memset(rbuf,0,sizeof(rbuf)),一切正常,有谁可以解释一下为甚么吗?
      

  5.   

    或者将其改为
    memset(rbuf,XX,sizeof(rbuf));XX不等于零!程序就正常呢.
      

  6.   

    不清楚为什么。
    但从程序逻辑上讲,应该在recv之前做memset
      

  7.   

    程序的错误原因就在memset(rbuf,0,sizeof(rbuf));这条语句上.将缓冲区中的字节全部设置为0,导致缓冲区大小strlen返回为0,接收缓冲区大小为零,接受的数据无法放入缓冲区,导致FD_READ事件一直存在,因此反复触发该消息处理函数,当然导致了死循环.
    感谢truemann(CodingWithJoy) 给的提示