如题!!!,请教高手

解决方案 »

  1.   

    描述不够清楚. 老是丢数据: 你指的是发送的时候丢数据,还是客户端接收的时候数据不完整.tcp发送不会丢数据的. 代码问题大.
      

  2.   

    TO:striking(硬撑者):
    服务器端分10000个包,每个包都有编号,在GetQue线程中投递WSAsend发送,在GetQue中得到发送字节数等于发送数,继续投递下一个WSAsend发送,依次循环,全部发送完后,结果客户端收到的全部数据小于服务器发送的数据?不知流程是否有问题,请指点,谢谢!!
      

  3.   

    另外我调用WSAsend时,有时候会返回WSAGetLastError() = WSA_IO_PENDING 的阻塞错误,并且WSAsend返回的发送字节数dwSendNumBytes为随机值,我投递WSAsend是在上一个GetQue返回后才投递的呀,怎么还会有WSA_IO_PENDING错误,难道GetQue返回了发送字节数等于wsasend的发送字节数的时候,SOCKET的系统发送缓冲还没有发送完?怎么还会阻塞,不应该呀?郁闷!!
      

  4.   


    WSAsend是一种重叠操作, 一般调用是立即返回, 当返回0 表示发送成功, 否则如果返回WSA_IO_PENDING 表示这时候系统正在发送数据, 那么你需要通过GetQue来获得此次发送的结果,
    到底是发送了几个字节(通过GetQue的参数dwSendNumBytes获知.)
      

  5.   

    我是这样呀,我是通过GetQue的参数dwSendNumBytes和WsaSend的发送字节数相同,说明全部发送完毕,才投递下一个WsaSend的,而且只是投递一个WsaSend,这时候WSAsend怎么还会阻塞呢?
      

  6.   

    那个不叫阻塞, 有时候网络原因, 发出1000个字节, 不是一下子就能全部发出去的, 所以会返回WSA_IO_PENDING (未决), 表示目前系统正在发送数据.当收到通知后, 根据dwSendNumBytes来判断此次发了多少字节, 比较一下, 剩下未发出去的, 再投递一次. 把剩余的发出去.
      

  7.   

    我是比较了呀,这些都没有问题,关键是我比较后,继续投递下一个WSASend的时候,怎么还会返回WSA_IO_PENDING呢?按理说这时候系统发送缓冲中应该都处理完了呀?
      

  8.   

    我把流程说一下,各位老大分析一下:
    客户端采用Csocket OnRecice后recv到信息直接写文件,不做其它事情。
    服务器端:线程A检测有没有发往客户端的信息,有的话就产生信息写入发送缓冲区a,判断该客户端SOCKET是否正在发送,如没有发送就PostQueuedCompletionStatus(m_hiocp, 0, (DWORD)lpmyio, &lpmyio->pSIOContext->ol); 通知完成端口开始发送数据。
    完成端口GetQue返回后就检测发送缓冲区a有没有等待发送的数据,有就取得数据投递WSASend发送,等下次GetQue返回时候判断发送字节是否等于需要发送数据,如确认相等后就继续从发送缓冲区a取下一条投递WSASend发送。
    如此循环,单步跟踪,发送10次数据都正常,单正常运行时候,发送2次后在WSASend时候就有WSA_IO_PENDING发生,看了WSASend参数dwBytes的值是一个很大的数,按常理说GetQue完成了才发下一条,系统缓冲不应该还有数据呀,不应该出现WSASend呀,请高手解答。
      

  9.   

    一定是你代码的问题。仔细的调试下。
    10个包一组,10个包一组的调试。把服务器的发送流程print出来,自然就清楚了。
      

  10.   

    这个问题我以前也碰过,客户端使用delphi的CClientSocket异步方式接完成端口的包时,老是丢,或数据不完整,累计发送 != 累计接收数,后来我使用ClientSocket阻塞方式,就不丢了,但是慢。再后来试了一下,vc的CSocket用异步方式也不丢数据,并且速度快。6000包,不到1秒就传完了。
      

  11.   

    我把流程说一下,各位老大分析一下:
    客户端采用Csocket OnRecice后recv到信息直接写文件,不做其它事情。
    服务器端:线程A检测有没有发往客户端的信息,有的话就产生信息写入发送缓冲区a,判断该客户端SOCKET是否正在发送,如没有发送就PostQueuedCompletionStatus(m_hiocp, 0, (DWORD)lpmyio, &lpmyio->pSIOContext->ol); 通知完成端口开始发送数据。
    完成端口GetQue返回后就检测发送缓冲区a有没有等待发送的数据,有就取得数据投递WSASend发送,等下次GetQue返回时候判断发送字节是否等于需要发送数据,如确认相等后就继续从发送缓冲区a取下一条投递WSASend发送。
    如此循环,单步跟踪,发送10次数据都正常,单正常运行时候,发送2次后在WSASend时候就有WSA_IO_PENDING发生,看了WSASend参数dwBytes的值是一个很大的数,按常理说GetQue完成了才发下一条,系统缓冲不应该还有数据呀,不应该出现WSASend呀,请高手解答。-----------------------------------------------------------------------------------我是菜鸟,我来说一下,你看看我的意思.
    你发送了,只是说你告诉系统去做这样一个IO操作,系统知道了之后,不一定立刻去做,但是他一定会去做,做完之后还会通知你做完了.这就是完成端口的作用.你发送了之后去看缓冲区肯定是有数据的,而且肯定会经常那个WSA_IO_PENDING错误的.这有什么不对呢?