您的位置:首页 > 理论基础 > 计算机网络

网络传输中send与recv需要注意的地方----------来自博客讨论

2015-06-18 19:46 519 查看


数据用send发出去后,recv一次应该接收多少?怎么知道接收完成了? [问题点数:20分,结帖人BeerGates]

不显示删除回复显示所有回复
显示星级回复显示得分回复
只显示楼主 

收藏






BeerGates
BeerGates
本版等级:


结帖率:94.03%
楼主发表于: 2008-08-03 08:52:10

send了一个1024K的东西出去,recv一次接收多少呢?当recv返回什么的时候才表示接收完成?

更多0分享到:

相关主题推荐: 数据

相关帖子推荐:

点击input获取全国各地的省市区

Oracle数据统计,麻烦大神帮我写几个sql语句

应该是向量问题。。。

导入数据数显乱码

Sql server 数据库设计的问题

sql语句执行效率低 求大神优化

php运行结果:Array ( )

Linq查询单张表数据时,怎样查出他关联的表的数据

准备好了么? 跳吧            !更多职位尽在 CSDN
JOB

数据抓取工程师(JAVA,Python)

广州酷旅旅行社有限公司
|

6-12K/月

我要跳槽

大数据开发高级工程师(日志监控及ELK方向)

上海安畅网络科技股份有限公司
|

15-25K/月

我要跳槽

数据仓库工程师

北京盛华合创科技有限公司
|

15-25K/月

我要跳槽

数据挖掘开发工程师

精硕世纪科技(北京)有限公司
|

15-25K/月

我要跳槽

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
回复次数:21




hhyttppd
hhyttppd
本版等级:


#1 得分:0回复于: 2008-08-03
09:35:21

1.recv一次接收多少

看recv的返回值(0完成,<0 出错)

2.recv返回什么表示接收完成。

int recv(

  SOCKET s,

  char FAR* buf,

  int len,

  int flags

);

If no error occurs, this function returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. 
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





arong1234
arong1234
本版等级:



#2 得分:2回复于: 2008-08-03
09:36:49

发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少

至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#3 得分:0回复于: 2008-08-03
13:18:43

引用 1 楼 hhyttppd 的回复:

1.recv一次接收多少 

看recv的返回值(0完成, <0 出错) 

2.recv返回什么表示接收完成。 

int recv( 

  SOCKET s, 

  char FAR* buf, 

  int len, 

  int flags 

); 

If no error occurs, this function returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. 

可是我怎么也得不到小于0的值呢?咋回事啊。

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#4 得分:0回复于: 2008-08-03
13:22:17

引用 2 楼 arong1234 的回复:

发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少 

至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节

先发送一个长度?这样吗?

send一次可以发多少的?我看书没介绍一次可以发多少数据?

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





arong1234
arong1234
本版等级:



#5 得分:2回复于: 2008-08-03
13:32:38

不要发大报文是个基本原则,我一般控制在1024左右,<1460一般比较好,但是其实没有啥规定,只是自己这么做而已

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#6 得分:0回复于: 2008-08-03
13:35:55

这样的啊?不知道大小限制如何?不知道有没有规定啊?

1024。

如果不知道大小,怎么才能接收完呢?
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





WinEggDrop
WinEggDrop
本版等级:


#7 得分:2回复于: 2008-08-03
14:12:04

有多少就接多少呀.如果不出现什么错误,肯定接完的.
对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#8 得分:0回复于: 2008-08-03
17:30:43

人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗?
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





WinEggDrop
WinEggDrop
本版等级:


#9 得分:0回复于: 2008-08-03
19:22:25

引用 8 楼 BeerGates 的回复:

人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗?

如果你是阻塞的socket,那你不断调用recv()就是,接到对方发完将socket断开;如果是异步等的socket,有数据要接收你就能收到消息或信号,然后调用recv()接数据,直到收完对方断开socket就是.
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





hxfjb
hxfjb
本版等级:


#10 得分:2回复于: 2008-08-03
21:37:39

tcp连接,你要自己定义一个发送和接收的协议;

1 你要知道你准备接收多少字节的数据,即是否接收了足够的数据可以进行处理了。

2 如果还没有接收足够的数据就断了(接收错误),那就断了,走人就行了。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





halve
halve
本版等级:


#11 得分:2回复于: 2008-08-04
11:43:39

引用 5 楼 arong1234 的回复:

不要发大报文是个基本原则,我一般控制在1024左右, <1460一般比较好,但是其实没有啥规定,只是自己这么做而已

其实我一直都有楼主这样的问题...

另外问问, 为什么不要发大报文是基本原则, 之前不是说一次发送大数据(例如 16 * 1024)比多次分发小数据(1024)好么?

如果说, 要把 数据/报文 的传输分开处理, 从而增加系统的复杂性, 没有 >>>足够的好处<<<, 我觉得还不如统一用大缓冲(16 * 1024)处理来的实际?

想听听你的高见 ;)
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





hhyttppd
hhyttppd
本版等级:


#12 得分:2回复于: 2008-08-04
17:22:56

《1460byte是只是个经验性规则,限制在单数据包不被分帧的情况下传输。

在大数据量的情况下,一次传很方便,我觉得也没什么不好的。

在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0).

对于由自己设计的传输协议,一般采用这样的包格式(tcp之上):

struct Packet_Header{

 ushort uSize;

 ushort uPaketId;         //可有可无,包格式编号

 DWORD  pData;

};

据具体的包格式,解析pData的数据。

因为,每次传输只需要取回前两个节做为传输长度即可验证数据是否完整。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





ok1234567
ok1234567
本版等级:


#13 得分:0回复于: 2008-08-05
09:46:07

可靠的方法

1、先发出一个传送数据的头结构,其中包含数据长度,接受端至少接受头结构的长度,然后决定后面的动作

2、有一个不会产生冲突的结束标记,比如HTTP头,就是由两对回车换行表示

任何数据传送前,先发送一个头结构,比较可靠,如果数据量不算太大,且不会产生编码混淆,可以定义一个结束标记

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





cwb0525
草帽
本版等级:


#14 得分:2回复于: 2008-08-06
21:54:12

在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0). 

对于由自己设计的传输协议,一般采用这样的包格式(tcp之上): 

struct Packet_Header{ 

ushort uSize; 

ushort uPaketId;        //可有可无,包格式编号 

DWORD  pData; 

}; 

就是这样,顶12楼~!
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#15 得分:0回复于: 2008-08-07
02:58:00

我试了一下,服务这边一发送成功的话。立即关闭,客户端就判断recv返回0了。立即不接收数据了。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





zgc7622
zgc7622
本版等级:


#16 得分:2回复于: 2008-08-07
16:58:32

使用TCP协议发送数据的时候,最好在数据的前面带上本次发送的数据长度,这样方便另一方的粘包处理。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





orbit
吹泡泡的小猫
本版等级:


#17 得分:2回复于: 2008-08-07
17:20:16

用select判断一下有没有数据可收,有就收,没有就等待,不需要确切知道要接收的数据大小
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





arvid_gs
arvid_gs
本版等级:


#18 得分:2回复于: 2008-08-07
19:26:02

可以用多种模型来实现,最简单得就是用select模型来实现了,接受端要实现解析组包的功能,因为多久收完依赖于网络环境,有可能1024需要分多次收完,所以必须做分析组包的功能,比如连续发很3个包,我们收到的时候可能是3或5次,这样必须解析组合成实际发送的包
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





yyunffu
yyunffu
本版等级:


#19 得分:0回复于: 2008-08-08
08:42:44

在异步模式下,如果数据接收完毕,select会一直等待到超时发生,实际上这个超时有两种情况,或者数据收完超时,或者网络状况原因超时,这个是无法判断是否完整接收到数据的。

所以还是应该有个明确的数据长度比较好。数据接收完成就断开,出错再重新请求,直到获取完整数据。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





BeerGates
BeerGates
本版等级:


#20 得分:0回复于: 2008-08-08
17:07:18

异步和Select模型有什么不同呢?
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理





nuaa_maliang
nuaa_maliang
本版等级:


#21 得分:0回复于: 2008-08-28
20:02:40

Send的太大或者太小都是不好的,超过1460的话,加上以太网的首部,超过MTU了,就会发生分片,不停的发太小的报文,导致糊涂窗口而且效率也很低。

Recv是本身是没有办法知道有没有收完的,TCP是一个无消息边界的流协议,SCTP才是有消息边界的,TCP只能告诉你这次收到了多少字节。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: