数据用send发出去后,recv一次应该接收多少?怎么知道接收完成了?

BeerGates 2008-08-03 08:52:10
send了一个1024K的东西出去,recv一次接收多少呢?当recv返回什么的时候才表示接收完成?
...全文
1124 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
nuaa_maliang 2008-08-28
  • 打赏
  • 举报
回复
Send的太大或者太小都是不好的,超过1460的话,加上以太网的首部,超过MTU了,就会发生分片,不停的发太小的报文,导致糊涂窗口而且效率也很低。
Recv是本身是没有办法知道有没有收完的,TCP是一个无消息边界的流协议,SCTP才是有消息边界的,TCP只能告诉你这次收到了多少字节。
yyunffu 2008-08-08
  • 打赏
  • 举报
回复
在异步模式下,如果数据接收完毕,select会一直等待到超时发生,实际上这个超时有两种情况,或者数据收完超时,或者网络状况原因超时,这个是无法判断是否完整接收到数据的。
所以还是应该有个明确的数据长度比较好。数据接收完成就断开,出错再重新请求,直到获取完整数据。
BeerGates 2008-08-08
  • 打赏
  • 举报
回复
异步和Select模型有什么不同呢?
arvid_gs 2008-08-07
  • 打赏
  • 举报
回复
可以用多种模型来实现,最简单得就是用select模型来实现了,接受端要实现解析组包的功能,因为多久收完依赖于网络环境,有可能1024需要分多次收完,所以必须做分析组包的功能,比如连续发很3个包,我们收到的时候可能是3或5次,这样必须解析组合成实际发送的包
吹泡泡的小猫 2008-08-07
  • 打赏
  • 举报
回复
用select判断一下有没有数据可收,有就收,没有就等待,不需要确切知道要接收的数据大小
zgc7622 2008-08-07
  • 打赏
  • 举报
回复
使用TCP协议发送数据的时候,最好在数据的前面带上本次发送的数据长度,这样方便另一方的粘包处理。
BeerGates 2008-08-07
  • 打赏
  • 举报
回复
我试了一下,服务这边一发送成功的话。立即关闭,客户端就判断recv返回0了。立即不接收数据了。
草帽 2008-08-06
  • 打赏
  • 举报
回复
在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0).
对于由自己设计的传输协议,一般采用这样的包格式(tcp之上):
struct Packet_Header{
ushort uSize;
ushort uPaketId; //可有可无,包格式编号
DWORD pData;
};

就是这样,顶12楼~!
ok1234567 2008-08-05
  • 打赏
  • 举报
回复
可靠的方法

1、先发出一个传送数据的头结构,其中包含数据长度,接受端至少接受头结构的长度,然后决定后面的动作
2、有一个不会产生冲突的结束标记,比如HTTP头,就是由两对回车换行表示

任何数据传送前,先发送一个头结构,比较可靠,如果数据量不算太大,且不会产生编码混淆,可以定义一个结束标记
halve 2008-08-04
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 arong1234 的回复:]
不要发大报文是个基本原则,我一般控制在1024左右, <1460一般比较好,但是其实没有啥规定,只是自己这么做而已

[/Quote]
其实我一直都有楼主这样的问题...
另外问问, 为什么不要发大报文是基本原则, 之前不是说一次发送大数据(例如 16 * 1024)比多次分发小数据(1024)好么?
如果说, 要把 数据/报文 的传输分开处理, 从而增加系统的复杂性, 没有 >>>足够的好处<<<, 我觉得还不如统一用大缓冲(16 * 1024)处理来的实际?
想听听你的高见 ;)
hhyttppd 2008-08-04
  • 打赏
  • 举报
回复
《1460byte是只是个经验性规则,限制在单数据包不被分帧的情况下传输。
在大数据量的情况下,一次传很方便,我觉得也没什么不好的。

在socket per transport情况下,视对方友好关闭为传输结束(recv 返回0).
对于由自己设计的传输协议,一般采用这样的包格式(tcp之上):
struct Packet_Header{
ushort uSize;
ushort uPaketId; //可有可无,包格式编号
DWORD pData;
};

据具体的包格式,解析pData的数据。
因为,每次传输只需要取回前两个节做为传输长度即可验证数据是否完整。
hxfjb 2008-08-03
  • 打赏
  • 举报
回复
tcp连接,你要自己定义一个发送和接收的协议;
1 你要知道你准备接收多少字节的数据,即是否接收了足够的数据可以进行处理了。
2 如果还没有接收足够的数据就断了(接收错误),那就断了,走人就行了。
arong1234 2008-08-03
  • 打赏
  • 举报
回复
发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少
至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节
hhyttppd 2008-08-03
  • 打赏
  • 举报
回复
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.
WinEggDrop 2008-08-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 BeerGates 的回复:]
人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗?
[/Quote]

如果你是阻塞的socket,那你不断调用recv()就是,接到对方发完将socket断开;如果是异步等的socket,有数据要接收你就能收到消息或信号,然后调用recv()接数据,直到收完对方断开socket就是.
BeerGates 2008-08-03
  • 打赏
  • 举报
回复
人家发,我不知道吧?recv有没有这个功能,知道已经把发送来的接收完了吗?
WinEggDrop 2008-08-03
  • 打赏
  • 举报
回复
有多少就接多少呀.如果不出现什么错误,肯定接完的.
BeerGates 2008-08-03
  • 打赏
  • 举报
回复
这样的啊?不知道大小限制如何?不知道有没有规定啊?

1024。

如果不知道大小,怎么才能接收完呢?
arong1234 2008-08-03
  • 打赏
  • 举报
回复
不要发大报文是个基本原则,我一般控制在1024左右,<1460一般比较好,但是其实没有啥规定,只是自己这么做而已
BeerGates 2008-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 arong1234 的回复:]
发送方发送前应该先发送一个长度信息,否则对方不可能知道自己该接收多少
至于接收缓冲大小,如果你发送的所有消息有最大长度,则设置为最大长度(超过1460字节就不要超过1460,因为报文一般都小于这个数,如果超过,会分成两个报文)我一般设计成1024字节或者2048字节
[/Quote]

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

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

加载更多回复(1)

18,357

社区成员

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

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