服务器是完成端口模型。
如果服务器要传几K的数据给客户端。 直接 WSASend就可以了 。然后客户端 recv 收到就完成了。我的问题来了。问题1: 如果要传几十K的数据,我在局域网试了下,客户端也可以一次全部recv(没有修改过发送或者接收缓冲区)。 这好像和我网上看到的说法相悖。
网上一般说默认缓冲区是8K。 那么我的数据怎么会一次都可以recv到。问题2: 如果数据大,要分包传,我在网上看到说服务器可以用send阻塞循环传 或者 分包传。能不能给个最好的思路?问题3: 我用的是 AccptEx 这个函数来异步接收到来的客户连接请求。 但是我处理不好恶意攻击(就是客户只连接不发数据)我是用队列管理 完成键 和 重叠结构。 自己看自己的程序都复杂。 希望好心人能帮忙解答下我的问题,能说多少说多少。或者能留下QQ 我加QQ请教下您。绝对不会耽误太多时间。  或者谁有这方面好的说明文档或者网址都可以发出来。 分不够再加。 谢谢了。 2天结账。

解决方案 »

  1.   

    1.你代码中的BufSize是多少? 也是几十K ?2.既然IOCP了,还是循环WSASend吧,3.关注!!
      

  2.   

    我服务器的完成端口在接受到客户请求之后 WSASend 的数据大小是50k,即里面的长度参数是 1024*50  。客户端是阻塞模式 直接int retbyte = recv()  retbyte是返回的字节数 这里也等于50k 说明一次全部接收到了.正常吗?我觉得好像和我知道的有点不一样,按道理说超过了系统缓冲区,WSASend是不可能一次发送成功50k的数据,而应该只能发送一部分的。回答者都有分,不够加。我这个新手真的谢谢各位了!
      

  3.   

    BOOL TransmitFile(
      SOCKET hSocket,
      HANDLE hFile,
      DWORD nNumberOfBytesToWrite,
      DWORD nNumberOfBytesPerSend,
      LPOVERLAPPED lpOverlapped,
      LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
      DWORD dwFlags
    );
      

  4.   

    你不用管系统怎么发的,你只管你上层的东西,TCP会自己处理分包和时序的问题
      

  5.   

    可是问题是有时候只能发送成功8K 因为缓冲区默认是8K  谁有IOCP详解之内的文档或者URL(要能说明问题的) 给我哦。分给你了。
      

  6.   

    问题1 好象没有太多讨论的必要,
    你的bufSize设的太大了,通常1024 ~ 1024 * 3个人意见~
      

  7.   

    我实际测试中发现,不管这个bufSize 设置为多少, WSASend 都可以一次把数据全部发送成功。 汗。。
      

  8.   

    IOCP参看下面文档
    http://www.joyvc.cn/NetworkAndCommunication/NetworkAndCommunicationGroup00221.html
      

  9.   

    以上问题全部作废!!!我现在就一个问题 回答我了就给全分socket 传输  服务器用 WSASend 为什么数据一大(比如几十K)的时候,客户端recv返回的值(就是接受到的字节数)就等于0  ? 
    如果服务器发送的数据很小(比如几百字节),客户端就可以正确的返回接收到的字节数。以上都是测试结果
      

  10.   


    怎么可能? #define DATA_BUFSIZE 1024
    CHAR Buffer[DATA_BUFSIZE];
    pSockInfo->DataBuf.buf = Buffer;
    pSockInfo->DataBuf.len = DATA_BUFSIZE;
    WSASend(pSockInfo->Socket, &(pSockInfo->DataBuf), 1, &SendBytes, 0,
                &(pSockInfo->Overlapped), NULL);
    你把这个DATA_BUFSIZE设成 1024 它能一次发几十K?
      

  11.   

    GetQueuedCompletionStatus(
     CompletionPort,    //完成端口对象
     &BytesTransferred, //接收字节数
     (LPDWORD)&pSOCKINFO, //单socket数据结构
     &lpOverlapped,      //OVERLAPPED
     INFINITE);打印BytesTransferred,这个是发出的字节,看它是多少,
    另外: 50K = 50 * 1024;
      

  12.   

    #define DATA_BUFSIZE 1024
        CHAR Buffer[DATA_BUFSIZE];
        pSockInfo->DataBuf.buf = Buffer;
        pSockInfo->DataBuf.len = DATA_BUFSIZE;    
        WSASend(pSockInfo->Socket, &(pSockInfo->DataBuf), 1, &SendBytes, 0,
                &(pSockInfo->Overlapped), NULL);
    程序确实是这样的。DATA_BUFSIZE = 1024     SendBytes = 1024*50 =50k  测试发现一次WSASend ,GetQueuedCompletionStatus() 会返回, 第二个参数返回值就等于50k 参看msdn 表示发送了50k数据
    但是客户端int ret = recv()  测试结果ret=0   。。 谁能告诉我为什么啊。我晕了。是局域网测试的。
      

  13.   


    谢谢你的回答。感觉有点用。。但是我是局域网,难道阻塞recv等不到完整的50k数据,还非要返回0表示数据不完整?
    阻塞recv应该不会只等待一下下把?
      

  14.   

    楼主说up也给分,于是我冒着自己贴被沉的风险,up
      

  15.   


    DWORD WINAPI WorkerThread(LPVOID CompletionPortID)
    {
    HANDLE CompletionPort = (HANDLE)CompletionPortID;
    DWORD BytesTransferred;
    SOCKINFO*  pSOCKINFO;
    DWORD  RecvBytes;
    DWORD Flags= 0;   
    OVERLAPPED* lpOverlapped;

    while(TRUE)
    {
    if (GetQueuedCompletionStatus(
    CompletionPort, //完成端口对象
    &BytesTransferred, //接收字节数
    (LPDWORD)&pSOCKINFO, //单socket数据结构
    &lpOverlapped, //OVERLAPPED
    INFINITE) == 0)
    {
    GXOnClose(pSOCKINFO);//自定义函数
    ::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("GetQueuedCompletionStatus错误错误"));
    continue;
    }

    if (BytesTransferred == 0)
    {
    GXOnClose(pSOCKINFO);
    ::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("BytesTransferred == 0"));
    continue;
    }
    if (!OnRead(pSOCKINFO, BytesTransferred))//自定义函数
    {
    GXOnClose(pSOCKINFO);
    ::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("OnRead函数过程发生错误"));
    continue;
    }

    if (WSARecv(pSOCKINFO->Socket, &(pSOCKINFO->DataBuf), 1, &RecvBytes, &Flags,
    &(pSOCKINFO->Overlapped), NULL) == SOCKET_ERROR)
    {
    if (WSAGetLastError() != ERROR_IO_PENDING)
    {
    AfxMessageBox("WSARecv发生严重错误!!");
    return 1;
    }
    }
    }
    }
    只是接收,参考<Windows网络编程第二版 中文版>第八章 
    源码目录: Windows网络编程第二版 中文版\原码\Chapter08\IOcmplt