当客户端连接服务器成功后,就触发了FD_WRITE,FD_READ,读写事件,所以我在连接成功后就发送数据到服务器端,服务器也能正常收到,以下是发送给服务器的消息
CString str;
str="hello";
send(csock,str,str.GetLength(),0);
可是当客户端退出时候,客户端代码如下:
shutdown(csock,SD_BOTH);
closesocket(csocket);csocket是客户但的socket
WSACleanup();
可是在服务器端仍能显示触发了FD_WRITE,FD_READ这连个事件。服务端采用的事件选择模型。
但是很奇怪的是,
这时候服务器端显示的收到的信息为“h”一个字母,而不时“hello”了。
谁能给解释一下阿?

解决方案 »

  1.   

    代码错误可能在服务器:
    理论上讲收到FD_WRITE通知发生在:
    ■ 使用connect或WSAConnect,一个套接字首次建立了连接。
    ■ 使用accept或WSAAccept,套接字被接受以后。
    ■ 若send、WSASend、sendto或WSASendTo操作失败,返回了WSAEWOULDBLOCK错
    误,而且缓冲区的空间变得可用;
    收到FD_READ 通知只发生在:
    缓冲区有数据可读(缓冲区指的是socket的接收缓冲区);
    建议楼主检测一下服务器的代码,还有当你客户端send()以后最好写上:str.Empty()( 清空)
      

  2.   

    快疯掉了,原来的问题还没有解决,又来信状况了:(我把大体的代码贴一下,大家帮我看看吧:(,真是郁闷
    服务器端的:
    SOCKET   m_sListen;
    WSADATA  wsaData;WSAEVENT m_wAccEvenArr;
    m_wAccEvenArr=WSACreateEvent();
    if(WSAEventSelect(m_sListen,m_wAccEvenArr,FD_ACCEPT|FD_CLOSE)==SOCKET_ERROR)
    {
        CString str;
        str.Format("%d",WSAGetLastError());
        AfxMessageBox(str);
        return FALSE;
    }DWORD dwIndex;
      dwIndex=WSAWaitForMultipleEvents(1,m_wAccEvenArr,FALSE,WSA_INFINITE,FALSE);       
       if(dwIndex==WSA_WAIT_FAILED)
      {
    AfxMessageBox(" ");
    return FALSE;
      }
       dwIndex=dwIndex-WSA_WAIT_EVENT_0;
     if(dwIndex==0)//FD_ACCEPT
     {
    WSANETWORKEVENTS wNetwokEvents;
    SOCKET sAccept=INVALID_SOCKET;
    if(WSAEnumNetworkEvents(m_sListen,m_wAccEvenArr,&wNetwokEvents) ==SOCKET_ERROR)
    {
    AfxMessageBox("WSAEnumNetworkEvents error");
    return false;
    }
    if(wNetwokEvents.lNetworkEvents&FD_ACCEPT)
    {
    if(wNetwokEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
                      {
                         AfxMessageBox("FD_ACCEPT error");

    }
     sAccept=accept(m_sListen,NULL,NULL);
    if(sAccept==INVALID_SOCKET)
    AfxMessageBox("Accept_Block error");

    WSAEVENT pRecvEvent;
            pRecvEvent=WSACreateEvent();

    while(true)
    {

              if(WSAEventSelect(sAccept,pRecvEvent,FD_WRITE|FD_READ|FD_CLOSE)==SOCKET_ERROR)
    {
       CloseHandle((HANDLE)pRecvEvent);
       CString str;
       str.Format("%d",WSAGetLastError());
      AfxMessageBox(str);
       break;
    }
    DWORD dwWaitResult;
    dwWaitResult = WSAWaitForMultipleEvents(1, pRecvEvent, FALSE,WSA_INFINITE,FALSE);
    if (dwWaitResult==WSA_WAIT_FAILED)
    {
    WSAEventSelect(sAccept, pRecvEvent[1], 0);
    CloseHandle(pRecvEvent);
    return FALSE;
    }
    dwWaitResult=dwWaitResult-WSA_WAIT_EVENT_0;

     if(dwWaitResult==0)
    {
      WSANETWORKEVENTS wNetworkEvents;
    if(WSAEnumNetworkEvents(sAccept,pRecvEvent,&wNetworkEvents) == SOCKET_ERROR)
    {
    WSAEventSelect(sAccept, pRecvEvent, 0);
    CloseHandle(pRecvEvent);
    return false;
    }
        if(wNetworkEvents.lNetworkEvents&FD_READ||wNetworkEvents.lNetworkEvents&FD_WRITE||wNetworkEvents.lNetworkEvents&FD_CLOSE)
    {
    if(wNetworkEvents.lNetworkEvents&FD_READ&&wNetworkEvents.iErrorCode[FD_READ_BIT]!=0)
    {
     WSAEventSelect(sAccept,pRecvEvent, 0);
              CloseHandle(pRecvEvent);
             AfxMessageBox("FD_READ  error");
    break;
    }
    else
    {
    AfxMessageBox("触发了读事件");
              int  nRet;
              int idx=0;
    char buffer[256];
    nRet=recv(sAccept,buffer,256,0);
                         
              if(nRet==SOCKET_ERROR)
    {
    CString str;
    str.Format("读错误º%d",GetLastError());
     AfxMessageBox(str);
             break;
    }
    else
    {
    CString str;
    buffer[nRet+1]='\0';
    str=buffer;
    AfxMessageBox(str);
    ZeroMemory(buffer,256);
    }
    if(wNetworkEvents.lNetworkEvents&FD_CLOSE)
    {
      AfxMessageBox("´触发了结束事件");
      closesocket(sAccept);
                  return TRUE;
    }
                 
    if(wNetworkEvents.lNetworkEvents&FD_WRITE&&wNetworkEvents.iErrorCode[FD_WRITE_BIT]!=0)
    {
      AfxMessageBox("FD_WRITE  error");
    WSAEventSelect(sAccept,pRecvEvent[1], 0);
      CloseHandle(pRecvEvent[1]);
    AfxMessageBox("FD_WRITE  error");
    break;
    }
    else
    {
      AfxMessageBox("´触发了写事件");
        
      int nLeft=pSocketInfo->bytesSend;
      int idx=0;
      int nRet;
    while(nLeft>0)
    {
     nRet=send(sAccept,&(pSocketInfo->bySend[idx]),nLeft,0);      if(nRet=SOCKET_ERROR)
    {
    AfxMessageBox("写错误");
        break;
    }
    nLeft=nRet;
    idx+=nRet;
    }
    } }
    WSAResetEvent(pRecvEvent[1]);
    }
       }

         return TRUE;
    }客户端的代码:
    客户端在廉洁成功后立即发送数据
    CString str;
    str="hello";
    send(csock,str,str.GetLength(),0);
    str.Empty();
    客户端推出时
    shutdown(csock,SD_BOTH
    closesocket(csock);1.在发送客户端退出的消息时,服务器端先是触发了读事件和写事件,然后显示触发了FD_CLOSE事件,然后又返回一个10038(要不就是10035错误),现在客户端有时候还连接不上,而且也不返回任何的错误信息。过一会重新执行时又好了
    2。我把大体的代码贴在上面了,还请大家耐心帮我看看哪里出了问题了。
      

  3.   

    http://www.vczx.com/article/show.php?id=711
    你可以参考一下我这个例子。