网络,可能的解决方案?

yuyunliuhen 2010-04-27 11:08:41
在学习网络的过程中,参考一些资料和自己的想法,

考虑的方案:

客户端打包发送,不使用SO_RCVBUF选项,
启用TCP_NODELAY选项,Nagle算法禁用。
使用Nagle算法,通过TCP发送的数据不会马上被发送,而是等待一段时间,当数据包大小达到缓冲区的大小再一次发送,这样就可能导致粘包现象。
(如果数据包长时间未达到缓冲区大小,是不是应该有个时间限制吧,猜测而已,不了解Nagle算法)此方法一般试用于每次发送数据比较小而且比较频繁的情况,

使用此方案,需要控制发送包的大小,如果用来做服务器,特别是游戏服务器,一般发包也不会太大,而且交互次数较频繁,效率比较低(使用Nagle算法的优势可以看到),但每个包的大小固定,至少发送数据包的时候,不会造成粘包。
而且不使用接收缓冲区,数据包发送后马上接收,也不会有几个包黏在一起,不用考虑粘包的问题。
一般看到的方案是,使用SO_RCVBUF,TCP_NODELAY不使用,发包的时候带个包头,发包进行打包处理,接包的时候根据包长度进行粘包处理。


IOCP发包重构问题
方案1
安排序列号,在每个ClientContext上两个序号,一个是某个套接字发包的序号(序号1),从接收到第一个包开始计数;另一个是套接字上读包的序号(序号2),这个包是计算当前读包的序列,从此套接字的第一个包开始读,依次递增;
同时,每个包也有一个编号(编号3),在投递WSARecv的时候,将编号1的值赋予编号3。
当读包的时候,对某个套接字上的包的序号(编号2)与将要读的包的序号(编号3)进行比较,
如果相等,则此包就是即将被读取的包;否则,包没有按顺序接收,将包放到ClientContext的未正确接收缓冲区包中,并对未正确接收缓冲区包按编号2进行排序,从未正确接收缓冲区包的第一个包开始读。


大家在研究网络过程中有什么好的想法活方案,或者以上想法分析权衡下,或者建议,都可发上讨论下,谢谢!
...全文
181 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
prodiving 2010-04-28
  • 打赏
  • 举报
回复
只投递一个很好处理, 处理完数据再投递下一个请求就不会处理那么麻烦,
但效率上和投递多个没测试对比过
yuyunliuhen 2010-04-27
  • 打赏
  • 举报
回复
thanks ^_^
King030609 2010-04-27
  • 打赏
  • 举报
回复
这么好!顶下
howema 2010-04-27
  • 打赏
  • 举报
回复
学习 绑定!
yuyunliuhen 2010-04-27
  • 打赏
  • 举报
回复
to bragi523:
禁用Nagle 以及不使用 SO_RCVBUF选项后 系统没有接收缓存,也会因为网络原因或接收不够快导致粘包么?
不过系统还是推荐使用Nagle的,还是定制好协议吧。

to:prodiving
嗯 ,投递多个WSARecv的时候 数据的顺序会发生改变吧,
如果每次只投递一个的话,是不是不会出现这个问题了呢

谢谢楼上两位 ^_^

prodiving 2010-04-27
  • 打赏
  • 举报
回复
Nagle算法确实是要根据应用的需求,像网络游戏的话就要关闭

IOCP发包重构问题你描述我晕了,没看懂,是担心多次WSARecv后,数据的处理顺序问题吗?
bragi523 2010-04-27
  • 打赏
  • 举报
回复
禁用Nagle依然有可能会出现粘包的,比如网络原因或者接收不够快等


所以还是要做好协议,接收定长包
yuyunliuhen 2010-04-27
  • 打赏
  • 举报
回复
up 丿

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧