本帖最后由 libincs007 于 2012-08-12 12:10:43 编辑

解决方案 »

  1.   

    1 真正删除在发送之后。可以通过WSAEnumNetworkEvents了解发生什么类型网络事件2 如果前一个还没发送,那么是的3 说明发送的太快了,来不及处理。你可以在处理函数中delete你可以看看这里
      

  2.   

      楼上回答了我的第二个问题,谢谢,但是不是我主要关注的,我想知道的是系统会拷贝我传递的内存不,什么时候通知我发送成功,怎么通知的,FD_WRITE只是说socket的缓冲区现在可以接收数据了。
      举个列子,比如我每次使用临时变量或全局变量buf[1024]来发送数据,那发生WSA_IO_PENDING的时候,我那变量里面的内容是不是会丢弃掉。
      

  3.   


    应该在FD_WRITE中发生数据case FD_WRITE:  // 可以发送数据了 {   // 进入无限循环   while(TRUE)   {     // 从文件中读取数据, 保存到 packet.data 里面.     in.read((char*)&packet.data, MAX_PACKET_SIZE);     // 发送数据     if (send(wparam, (char*)(&packet), sizeof(PACKET), 0) == SOCKET_ERROR)     {       if (WSAGetLastError() == WSAEWOULDBLOCK)       {         // 发送缓冲区已经满了, 退出循环.         break;       }       else // 其他错误       {         // 显示出错信息然后退出.         CleanUp();         return(0);       }     }   } } break;
      

  4.   

    不会,自己写packet的东西不会丢,只是没有发送出去。如果这时候继续往packet里写东西,那么里面原来的数据就会丢失
      

  5.   

    再请教下,packet的东西不会丢,是不是发生缓冲区满的时候,packet中的数据已经拷贝的socket的缓冲区了,下次进入while循环会更改packet中的内容,那上次packet中的数据不会丢失?那while发送就是正确的了,如果packet没拷贝到缓冲区,那每发生一次缓冲区满,就可能会丢失部分数据。
    while(true)
    {
    in.read((char*)&packet.data, MAX_PACKET_SIZE); //每次都更改packet内容   
    send(packet);//发生缓冲区满,此时packet中的内容会拷贝到socket缓冲区?
    }
      

  6.   

    要根据WSAGetLastError() 判断
    如果是WSA_IO_PENDING说明已经成功的复制到缓冲区,发送会在稍后完成
    如果WSAEWOULDBLOCK,则说明已经满了,没有拷贝到缓冲区。则要等待一段时间再发送纠正一下前面说的2 如果我调用WSASend(),并返回了WSA_IO_PENDING,那我马上又调用一次WSASend(),那会同样返回WSA_IO_PENDING吗?如果缓冲区没有满,则是的。一般情况下发送不会失败也谢谢LZ,很多东西我也更清晰了
      

  7.   

    如果没有发送完,需要投递下一次WSASend;
    如果没有发送完,缓存就不释放,开发者需要保证缓存的有效性;按照我的猜测,你的代码不会返回WSA_IO_PENDING,原因是:
    如果你使用重叠IO,那根本不用什么WSAEventSelect模型;
    如果你用WSAEventSelect模型,那你的WSASend最后两个参数应该是NULL,此时如果你的套接字是阻塞的,那么WSASend要一直阻塞直到发送完成,如果是非阻塞的,那就会马上返回,并且至少发送了部分数据(因为你既然用了WSAEventSelect模型,那么在WSASend的时候,一定是可写状态)。所以,数据总是会发完的,不会像你说的,每次都返回WSA_IO_PENDING(其实不会返回WSA_IO_PENDING,这里我理解为返回无法发送——套接字缓存满),它总是趋向于发送完成的。