如题 目前小弟在封装一个TCP网络通信类 遇到一点小疑问
在同步方式发送与接收数据是 数据是按照顺序发送的 我可以使用WriteLine方式一行行发送 在客户端可以开线程使用ReadLine方式读取 没有问题
现在为了提高性能 我想使用异步方式发送数据 但是还有一些疑问
比如我向一个Client用异步的方式发送了10条包含换行符("\r\n")的字符串 在客户端使用同步的ReadLine方式接收的时候 会不会出现10条字符串相互错乱的问题
也就是说 向一个Client异步发送10条数据 在系统内部是一条条发送 还是同时发送10条
如果同时发送10条 那我客户端使用同步的ReadLine方式是不是就会出现错误 那我在客户端使用异步接收的方式可以避免这个数据错乱吗还请各位大侠仗义相救

解决方案 »

  1.   

    如果发送一个消息使用一个BeginSend(而不是多个),那么接收端得到的这个消息一定也是连续的,不会出现这个消息的一部分跟其它消息的一部分混合的现象(tcp协议会正确地装配消息)。如果你执行10个beginSend命令,那么接收端收到消息的次序当然是不确定的,这是在发送时就决定了的,因为线程中的方法运行次序并不确定。tcp的特点是有一定延迟,以便对网络带宽的占用降到最低,它会同时发送多条消息。在每一条信令都应该设计有(业务意义上的)序列号,这样就不会硬要弄成(不可取的)顺序的序列。
      

  2.   


    感谢您的回复 小弟想再追问一下 是否可以在客户端同时开十个异步接收 可以同时接收到这十条数据吗 如果可以的话 是不是意思就是他们十个各顾各的不会产生影响呢
    另外 我在服务端开启监听后 为了提高性能 同时开启了200个BeginAcceptTcpClient来接收TCP连接 然后开线程通过循环将BeginAcceptTcpClient保持在200个 这样是否能够比我在接收到一个Client的CallBack中再次创建一个BeginAcceptTcpClient性能高 我这样的设计方法有没有问题呢
    还请大侠赐教
      

  3.   


    另外 我看到C#网络高级编程中的异步发送示例中 在StreamWriter.BaseStream.BeginWrite()后面直接跟了StreamWriter.BaseStream.Flush() 按照我的理解 执行完第一句后 数据还没有发送完就执行了flush 这样难道没有问题吗?按照我的理解 应该在EndWrite()后面加Flush()才对啊
      

  4.   

    异步也有不同的操作模式,最简单的使用socket.beginSend之类的处理,你是没法控制其先后顺序,但如果你完全自行设计一种异步发送方式,如下:
    循环线程1:  程序生成数据包->加入传输队列
        循环线程2:       从传输队列取数据包-〉压缩数据包-〉加入发送队列
             循环线程3:               从发送队列取数据->Socket.Send。                                
    在上面三个异步操作中,你是可以控制发送的先后顺序的。接收也是类似。
      

  5.   

        另外,生成的数据包可能是100KB,而发送出的数据块可能只有2KB, 期间的数据分割及合并工作可以由内部通信队列处理,这样就可以保证每个数据包的顺序,也最终保证了接收数据包的完整及可靠性。    而业务层只关心收发的数据包即可,可以通过制定数据报包协议的方式来确定数据包的类型与操作。进而控制业务流转。