这个问题让我纠结了一天,看了不少资料没找到合适的答案。
问题是收到的数据会发生所谓的粘包现象!包的大小不确定,可以很大,最大可以用满投递的读缓存的大小,4K,这个有上限吗?该如何怎样去拆包:网上说需要用到环形缓冲区或者双缓冲区,他们的原理很好理解,但是我想如果客户端很多,每个连接(考虑连接数可能有1W)都配一个或者两个缓冲区拼接数据(这里应该不用考虑包的顺序会乱?因为我的协议包用的是起始和结束标志),这样是不是要开另外一个内存池?!另外,必须每次先把收的数据拷贝到这些缓冲区,但是据说拷贝数据也会带来不少的开销!
因为投递读操作的缓冲区是在一个内存池之中,而环形缓冲区或者双缓冲区的大小也比较大,这样一来,内存的使用很可观啊,虽然内存很便宜。还是说有其他方案吗?假设使用环形缓冲区,需要把拆包的过程放到另外的一个或者多个线程吗?这个线程只是遍历所有的环形缓冲区做拆包工作,然后把拆出来逻辑包扔到另外一个队列,交由其他的一个或多个线程解包?
问题先到这里吧!刚接触服务器开发,感觉开发服务器水很深!希望经验丰富的各位指点一二,不胜感激。TCP/IPiocp服务器内存

解决方案 »

  1.   


    server开发很容易.
    高强度,不崩溃,无bug的server很难.
      

  2.   

    看看我的st_asio_wrapper框架,里面自带默认解包器。
    实际怎么解包要看你的协议,我的只是参考。http://blog.csdn.net/yang79tao/article/details/7724514
    svn checkout http://st-asio-wrapper.googlecode.com/svn/trunk/ st-asio-wrapper-read-only
      

  3.   

    打算尝试在接收线程里面直接对每个接收buffer进行拆包,不完整的包memcpy到buffer头部,然后继续投递这个buffer,可能比使用环形缓冲区更高效。
      

  4.   

    有个方法供参考,IOCP不需要理解报文内容,只完成简单接收、发送投递,业务层获取数据后,先从包头中获取业务数据长度,然后返回给IOCP,IOCP根据长度申请指定长度Buffer,一旦这个buffer满,则本次接收数据拼包完成.
      

  5.   

    我当时的做法是这样的。所有的网络数据数据用base64编码,在一条数据发送完成后,发送一个结束标志给服务器,如“;”在服务器接收的对列中,数据时这样的:abc123#=123;cuj#=dsf;dsfdjg==.....(base64中没有“;”)这样服务器查找缓存,解析字符串,就可以获取数据。如上,可以得知已经传输完成两个命令。第三个命令还没完成,因为没有;
      

  6.   

    对TCP流的概念理解清楚, 这类长度不定的解包, 最简单的方式就是以
    长度 + 数据 + 长度 + 数据 的形式来发送, 这样就可以在服务器先读取长度, 再拿出对应长度的缓冲, 直到缓冲满了就可以处理, 然后再读取下一次的 长度, 再解释出数据, 如此循环而已.
      

  7.   

    谢谢各位,我也感觉使用起始结束标志有弊端,因为没收完整的包要每次memmove到接收缓冲区的前面,目前还不知道在大量请求到来时是否会带来性能缺陷。