免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7301 | 回复: 7
打印 上一主题 下一主题

[C] 服务器端如何处理socket粘包的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-13 19:11 |只看该作者 |倒序浏览
有个程序,服务器端用socket编写,接收tcp请求,客户端用libcurl发送http request.

现在的问题是:服务器端accept到的socket没有客户端发送的那么多,少了很多.

有人说这是因为socket粘包的问题.

我现在服务器端的处理逻辑是:每次最多read()4096个字节的,然后处理里面完整的http请求(用\r\n\r\n结尾标示),然后继续,如果当前的接收buffer里面没有完整的http request,则继续read(),直到read()返回0或者-1,才跳出循环,close()掉socket.

但是,这样感觉第一是其慢无比,第二是,同样丢包.

不知道大家遇到这么这种情况下都怎么处理的,求指点.



论坛徽章:
0
2 [报告]
发表于 2012-12-13 23:08 |只看该作者
   对http协议,粘包应该不是问题吧,毕竟http协议是由固定的分隔符的.只要网络环境不是太繁忙,TCP也不会丢包的.这样的问题多半是应用程序代码的问题.
   客户端调用write操作后,必不意味着TCP就将数据都发给了服务端,什么时候发,怎么发,完全是由TCP协议决定的.应用程序能做的就是通过设置socket option尽量让TCP马将数据发送出去.你可以将服务端的tcp缓冲区设大点,或是一次read尽量多的数据.

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
3 [报告]
发表于 2012-12-14 11:25 |只看该作者
TCP是流协议,从来就没有什么粘包问题。

论坛徽章:
0
4 [报告]
发表于 2012-12-14 12:06 |只看该作者
用wireshark抓包看看,先确定问题是在客户端还是在服务端,不过,你得把服务端跟客户端分开在两台机子上跑,因为,只在一台机子上跑的话,数据包不经过网卡,不经过网卡就抓不到包。如果问题在服务端,不妨把接收到的数据打Log,然后对照抓的包看,是不是你接收的问题

论坛徽章:
0
5 [报告]
发表于 2012-12-14 12:08 |只看该作者
zhaohongjian000 发表于 2012-12-14 11:25
TCP是流协议,从来就没有什么粘包问题。

正因为,它是流的,所以没有消息边界,就像你看水流一样,你知道通,那里是开头,那里是结尾吗?

论坛徽章:
0
6 [报告]
发表于 2012-12-14 12:11 |只看该作者
我现在的策略是:read() socket直到 return 0或者-1,正在测试,貌似保证了正确性,不丢请求了.

但是,很显然,read()在返回0/-1以前会block()很长一段时间.

所以现在很慢很慢.

不知道我这个方法对不对,如果只有这么一个法子,我准备接收算法就这样了,多开几个线程来解决效率问题.

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
7 [报告]
发表于 2012-12-14 12:39 |只看该作者
耗资喜欢猫 发表于 2012-12-14 12:08
正因为,它是流的,所以没有消息边界,就像你看水流一样,你知道通,那里是开头,那里是结尾吗?


你想说什么?TCP不负责告诉你哪里是开头哪里是结尾,因为TCP是流,它对用户不区分包,自然也就没有什么“粘包”问题。

所谓粘包,不过是一些人一厢情愿的认为TCP应该提供分包的功能罢了。

论坛徽章:
0
8 [报告]
发表于 2012-12-15 18:58 |只看该作者
linux平台吗, 试试epoll吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP