技术宅的结界

 找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 1311|回复: 10
收起左侧

【原创】关于TCP程序很容易让人误解的一个细节

[复制链接]

36

主题

146

帖子

7193

积分

用户组: 管理员

UID
77
精华
11
威望
115 点
宅币
6630 个
贡献
132 次
宅之契约
0 份
在线时间
108 小时
注册时间
2014-2-22
发表于 2017-8-21 20:46:51 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有帐号?立即注册→加入我们

x
玩socket貌似很简单,socket常用的函数不超过20个。但是一些细节如果没理解,那么开发的程序很可能会在你意想不到的情况下崩溃,而且很难在本地测试中出现

一个最简单的send调用如下:
  1. send(s,b,100,0);
复制代码
意思很简单,发送100个字节。按理说,接收只要这么写就行了:
  1. recv(s,b,100,0);
复制代码
本质上说,这段代码非常正确,而且会在本地环境、局域网环境甚至在优良的公网环境下正确运行。但是在网络差的时候,就有点悲剧了。因为:你很有可能无法一次性接收完毕这100个字节!
下面就要说重点了:关于对TCP可靠性理解的误区。
很多人包括我以前在内,对TCP可靠性的理解就是:一次性成功发送多少字节,就能一次性成功接收多少字节。这个理解是大错特错的。
TCP“可靠”的意思是,你一次(或多次)发送了N字节,对方就能收到N字节。但是不能保证对方调用一次recv就能接受完毕(即使缓冲区足够大)!
因此,要想完整地接收到100字节,最SB的办法就是循环调用100次recv(s,b,1,0),也可以根据RECV的返回值(接收了多少字节),动态叠加。
此外需要注意的是send和recv的返回值类型是int,因此可能出现三种情况:正数、0、负数。它们的含义分别是:
返回正数:发送/接收了多少字节。
返回0:对方断开了。
返回负数:调用失败。

最后是干货:一个传输文件的程序源码(在糟糕网络环境下运行无误)。
游客,如果您要查看本帖隐藏内容请回复

1044

主题

2345

帖子

5万

积分

用户组: 管理员

一只技术宅

UID
1
精华
218
威望
294 点
宅币
18326 个
贡献
37541 次
宅之契约
0 份
在线时间
1749 小时
注册时间
2014-1-26
发表于 2017-8-21 21:18:36 | 显示全部楼层
确实不少人对socket都存在着各种各样的误解,而且还有人自己在tcp的基础之上封装所谓的“更可靠的协议”的。

一次性成功发送多少字节,就能一次性成功接收多少字节

有关这句话:其实这是UDP的特性。你要么接不到包裹,要么接到的包裹是100%正确并且不会出现包裹粘连和拆分的情况。

此外,TCP不需要考虑包裹顺序的问题,它自己就能实现排序过程,毕竟它是在模拟文件流。这也是为什么很多人问我怎么解决“粘包”的问题。因为他们以为TCP会自动处理所谓的“分包”。然而文件流就是像读文件那样一点点读取和分析的过程。
作为对比,UDP不用考虑分包的问题,因为超过MTU的包会被丢弃。以及,UDP无法保证包裹能够按照发送的顺序来接收。你按顺序发出A, B, C, D四个包,接收方甚至能以D, C, B, A这样的顺序来接收。

26

主题

114

帖子

1620

积分

用户组: 版主

UID
1821
精华
6
威望
67 点
宅币
1291 个
贡献
51 次
宅之契约
0 份
在线时间
258 小时
注册时间
2016-7-12
发表于 2017-8-25 05:32:55 | 显示全部楼层
有时候处理了拆分问题 却又忘记处理合并问题!

2

主题

61

帖子

458

积分

用户组: 中·技术宅

UID
2364
精华
0
威望
0 点
宅币
397 个
贡献
0 次
宅之契约
0 份
在线时间
53 小时
注册时间
2017-3-30
发表于 2017-9-19 18:07:18 | 显示全部楼层
在糟糕网络环境下运行无误

0

主题

18

帖子

51

积分

用户组: 小·技术宅

UID
2933
精华
0
威望
2 点
宅币
29 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2017-10-9
发表于 2017-10-9 17:52:18 | 显示全部楼层
有时候确实不会考虑这么多,还是要从一开始养成好习惯

1

主题

85

帖子

91

积分

用户组: 小·技术宅

UID
3026
精华
0
威望
1 点
宅币
3 个
贡献
0 次
宅之契约
0 份
在线时间
6 小时
注册时间
2017-10-31
发表于 2017-11-5 18:34:41 | 显示全部楼层
学习了。
回复

使用道具 举报

0

主题

9

帖子

35

积分

用户组: 初·技术宅

UID
4521
精华
0
威望
2 点
宅币
22 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2018-11-30
发表于 2018-12-1 09:25:15 | 显示全部楼层
这个是不是要看看呢

0

主题

44

帖子

60

积分

用户组: 小·技术宅

UID
4536
精华
0
威望
2 点
宅币
12 个
贡献
0 次
宅之契约
0 份
在线时间
6 小时
注册时间
2018-12-6
发表于 2018-12-6 11:36:27 | 显示全部楼层
学习了一下

0

主题

3

帖子

22

积分

用户组: 初·技术宅

UID
4899
精华
0
威望
0 点
宅币
19 个
贡献
0 次
宅之契约
0 份
在线时间
3 小时
注册时间
2019-4-30
发表于 2019-4-30 01:05:58 | 显示全部楼层
虽然是个比较基础的问题, 但确实有些人不知道. 支持.

0

主题

2

帖子

13

积分

用户组: 初·技术宅

UID
4913
精华
0
威望
0 点
宅币
11 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2019-5-3
发表于 2019-5-4 10:35:40 | 显示全部楼层
学习学习
回复

使用道具 举报

0

主题

1

帖子

17

积分

用户组: 初·技术宅

UID
5202
精华
0
威望
0 点
宅币
16 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2019-8-7
发表于 2019-8-24 16:56:03 | 显示全部楼层
学习到了
回复

使用道具 举报

本版积分规则

QQ|申请友链||Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2019-11-14 15:14 , Processed in 0.109106 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表