TCP服务器有多线程,每个线程都可能随时使用同一个socket发送数据到客户端,数据是数据包的形式,每个包不定长,但是每个包的最前面有包头,包括后面数据包的内容,总长和版本信息。现在出现的问题是,由于服务器是多线程的,客户端收到一个数据包头后,发现有时候在包头后跟的信息并不是这个包头应该跟的信息,也就是说每个数据包被错开了,我已经在服务端socket使用了TCP_NODELAY,包头和数据体也是一次发送的(同一个send),但似乎并没有解决问题。
请问这个问题如何解决?

解决方案 »

  1.   

    你如果不是用异步的发送,应该不会有这样的问题。如果是wsasend,这样的问题是会出现的,在常见的异步socket中,都要判断result中的数据是否发送完,如果没发送完,这时另一个wsasend发生,包就会乱了。
      

  2.   

    如何“判断result中的数据是否发送完”?
      

  3.   

    多个线程对同一个SOCKET操作,不管对哪种模型来说都是说不通的,也就是说有点畸形。
    建议楼主修改模型吧。下苦功夫,长痛不如短痛。
    要不然就用异步模型,并且对SOCKET操作时加锁。
    当发送或接收时返回-1,并且wasgetlasterror返回10035,表示前一个IO还没有完全传递,需要等待一下。可以sleep 10毫秒。
      

  4.   

    服务端需要同时运行于windows和Linux平台,现在的现象在windows中不存在。
      

  5.   

    wsasend会牵扯到overlap结构,其中包括了发送缓冲区的指针,以及要求发送的字节数,当操作完成时,你一定要判断实际发送的字节数,在某些情况下实际发送的字节数会比要求的数字小。意味你要发送的字节数并未完全完成(partial),试想如果这是你在另外一个线程里在同一socket上wsasend,可想结果了,估计就是你看到的情况。