我采用的是重叠I/O模式之事件通知编程;现在有这样一个问题:当客户端传递字符串给服务器的时候,函数WSAGetOverlappedResult()是否一次获得到字符串长度值,也就是说该函数的参数lpcbTransfer是否一次性获得字符串的长度值;函数WSARecv()是否一次性获得字符串,如果WSARecv没有一次获得字符串,那么如何处理才能不会让服务器端多次接收完客户端发送的字符串;
例如客户端发送字符串:abcdefg;函数WSAGetOverlappedResult()中的参数lpcbTransfer的值是否是7(或者分两次:一次是5,一次是2)?,函数WSARecv()可能一次接收到abcdefg(或者分两次接收,一次接收到abcde,再一次接收到fg?

解决方案 »

  1.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 
      

  2.   

    先用缓存接受字符串,判断是否接受完整。不完整就重复接受,当然要设偏移地址。
    例:        int nReadCount = 0;
    int nOffset = m_nRecvBytes;
    int nBuffSize = (int)sizeof(m_dataBuffer) - nOffset;
    char *szDataBuff = m_dataBuffer + nOffset;
    nReadCount = recv(m_hSocket, szDataBuff, nBuffSize, 0);接受完了,清除缓存,m_nRecvBytes置零
      

  3.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
      

  4.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    重叠IO模式不能处理吗?
      

  5.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?
      

  6.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?如果你一定要收到7字节再处理  你用异步方式 你可以收到5字节先把数据存起来 再收到2字节再一起处理如果你一定要一次就收到7字节  那只有用阻塞模式...
      

  7.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?如果你一定要收到7字节再处理  你用异步方式 你可以收到5字节先把数据存起来 再收到2字节再一起处理如果你一定要一次就收到7字节  那只有用阻塞模式...
    服务器如何知道客户端传递过来几个字符?
      

  8.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?如果你一定要收到7字节再处理  你用异步方式 你可以收到5字节先把数据存起来 再收到2字节再一起处理如果你一定要一次就收到7字节  那只有用阻塞模式...
    服务器如何知道客户端传递过来几个字符?那你怎么知道一次没收完?
      

  9.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?如果你一定要收到7字节再处理  你用异步方式 你可以收到5字节先把数据存起来 再收到2字节再一起处理如果你一定要一次就收到7字节  那只有用阻塞模式...
    服务器如何知道客户端传递过来几个字符?那你怎么知道一次没收完?
    我测试过,如果发送一串字符串,那么服务端就分好几次接收;
      

  10.   

    如果客户端传递过来字符串:abcdefg,服务器端分了两次接收到,但是我想一次性处理接收到的字符串;那服务器端应如何处理? 你一定要一次就收完你想要的   那只有阻塞模式了...
    并不是一定要用阻塞模式,如果现在用重叠模式的话,那么程序要如何处理一下?如果你一定要收到7字节再处理  你用异步方式 你可以收到5字节先把数据存起来 再收到2字节再一起处理如果你一定要一次就收到7字节  那只有用阻塞模式...
    服务器如何知道客户端传递过来几个字符?那你怎么知道一次没收完?
    我测试过,如果发送一串字符串,那么服务端就分好几次接收;服了你了 你自己不定义相关的协议怎么保证一次完整的消息处理一次?要是客户端先发1234 再发56  你服务器做的再好也不知道客户端是发了2次 一次1234 一次56 你又怎么确保服务器一次收完? 不知道你为什么一定要纠结于服务器要一次收完  你这样毫无规律的数据  怎么一次收完?
      

  11.   


    不是说了 要自己定协议自己封包么? 你客户端每次发送字符串前先发送一个int表示接下来发送的字符串多长
    比方你发送123456 你int len=6 先发送len再发送“123456”  服务器先收4字节的int 收到len==6 再收6字节的字符串  然后再显示“123456”  
      

  12.   

    网上给出的代码好像没有处理这种情况,下面是我从网上摘取的一部分代码: while(TRUE)
    {
    Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
    if ( Index== WSA_WAIT_FAILED)
    {
    printf("WSAWaitForMultipleEvents() failed %d\n", WSAGetLastError());
    return 0;
    }else
    printf("WSAWaitForMultipleEvents() is OK!\n");
    // If the event triggered was zero then a connection attempt was made
    // on our listening socket.
    s=Index - WSA_WAIT_EVENT_0;
    if ((Index - WSA_WAIT_EVENT_0) == 0)
    {
      WSAResetEvent(EventArray[0]);
    continue;
    }
     
    SI = SocketArray[Index - WSA_WAIT_EVENT_0];
    WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
    if (WSAGetOverlappedResult(SI->Socket, &(SI->Overlapped), &BytesTransferred, FALSE, &Flags) == FALSE || BytesTransferred == 0)
    {
    printf("Closing socket %d\n", SI->Socket);
    if (closesocket(SI->Socket) == SOCKET_ERROR)
    {
    printf("closesocket() failed with error %d\n", WSAGetLastError());
    }else
    printf("closesocket() is OK!\n");
    GlobalFree(SI);
    WSACloseEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
    // Cleanup SocketArray and EventArray by removing the socket event handle
    // and socket information structure if they are not at the end of the arrays
    EnterCriticalSection(&CriticalSection);
    if ((Index - WSA_WAIT_EVENT_0) + 1 != EventTotal)
    for (i = Index - WSA_WAIT_EVENT_0; i < EventTotal; i++)
    {
    EventArray[i] = EventArray[i + 1];
    SocketArray[i] = SocketArray[i + 1];
    }
    EventTotal--;
    LeaveCriticalSection(&CriticalSection);
    continue;
    }
      

  13.   


    不是说了 要自己定协议自己封包么? 你客户端每次发送字符串前先发送一个int表示接下来发送的字符串多长
    比方你发送123456 你int len=6 先发送len再发送“123456”  服务器先收4字节的int 收到len==6 再收6字节的字符串  然后再显示“123456”  
    不知道网上有这方面的例子吗?