关于网络数据接收后, 如何确定其边界?

amziwei 2006-01-04 11:08:44
偶还是菜鸟, 对这个问题一直不明白, 参考了好几本这方面的书, 都说的含糊, 所以只好来这里问了.
谢谢各位朋友!

是这样的:

服务器端A
客户端B

A有两组数据,
char a[10]="123456789";
char b[10]="abcdefghi";

A要把这两组数据发到B

以下是我从一本参考书中抄出来的:

(当服务器A调用send后) 如果协议还没有开始发送缓冲区中的数据,或者缓冲区中没有数据, 那么send就比较缓冲区的剩余空间大小和待发数据长度len, 如果......, 如果len小于或等于缓冲区的剩余空间的大小, send 就把待发数据copy到剩余空间里去......

问题是:
如果发送缓冲区大小为 100 字节, 服务器A send 数据a后,立即send数据b, 按照上面所说, 数据a填到缓冲区后,缓冲区还剩下90字节, 于是数据b也会被填到缓冲区里, 接着, 这两组数据a b会被协议当作一个数据包发出去.
这样的话, 客户端B在收到这个包后, 怎么知道这个包中是有一组还是两组数据? 怎么确定两组数据的边界?


另外, 哪位朋友有send sendto, recv recvfrom 这四个函数的详细讲解吗?
望不吝告知.
谢谢!
...全文
346 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xianshiqi 2006-01-08
  • 打赏
  • 举报
回复
发送方粘包与自己的程序,机器,环境有关,这个是不可避免的。
可以自己编写回传确认信息。
amziwei 2006-01-06
  • 打赏
  • 举报
回复
TCP会自己校验的, 在TCP协议下, 到达接收方的数据是正确的,顺序保证的流

但是UDP是怎么样的我不清楚, 所以在这里向大伙请教

UDP的"不可靠", 我想, 指的是: 发送方在发出一包数据后, 并不保证接收方会收到, 但是, 一旦接收方用 recvfrom 收到数据后, 这包数据一定是正确完整的. 在UDP协议内部, 如果数据到达接收方后, 但是数据是错误的, 那么协议会丢掉此包, 不会让 recvfrom 收到数据, 也不会触发"接收"事件(在异步模式下).

是不是这样的呀?
vc_asm 2006-01-06
  • 打赏
  • 举报
回复
正确的
yingpf 2006-01-06
  • 打赏
  • 举报
回复
还没考虑过这个问题,我想是发送方的一次send对应接收方的一次recv吧,是不是同一个数据包的数据,协议会判断的吧
amziwei 2006-01-05
  • 打赏
  • 举报
回复
谢谢两位!

to zhaolaoxin()兄
"没有这么复杂,客户端每一个recv()对应服务器的一个send(),你只需要区分每一个send()是什么含义即可"


如果是 sendto 和 recvfrom 呢?
nuaawenlin 2006-01-05
  • 打赏
  • 举报
回复
tcp的话,最好加上数据头和数据尾

udp是有边界的,不需要判断
amziwei 2006-01-05
  • 打赏
  • 举报
回复
以下一段话来自CSDN朋友的问答:

每个UDP数据报有一定的长度,如果数据报最终正确地到达目的地(即分组到达目的地且校验正确),数据报的长度将传递给接受方的应用进程。这与TCP这样的字节流协议(无记录边界)是不一样的。

如上所说, UDP数据报"最终正确地到达目的地", 这个校检是UDP协议自已完成的, 还是要我自己去完成?
即是说, 比如上面的服务器A调用sendto发送数据a给客户端B, 只要B用recvfrom收到数据, 是不是UDP会保证这包数据是正确的(即是正确完整的a)?
还是要我自己去校检?
lishan2002 2006-01-05
  • 打赏
  • 举报
回复
关于粘包http://lijinshui.bokee.com/2401025.html
gnixemos 2006-01-05
  • 打赏
  • 举报
回复
tup自己定义长度就可以了

udp不存在边界的问题
amziwei 2006-01-05
  • 打赏
  • 举报
回复
谢谢上面两位

以下一段文字来自lishan2002的链接:

发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

由上所说, TCP 是会出现粘包的

UDP 呢?
nuaawenlin说"UDP是有边界的,不需要判断"
是不是说, 在UDP环境下, 不论待发数据有多小, 协议会立即将其发送出去, 而不是像TCP那样, 收集了多个数据后才当作一个包发送出去, 是不是这样?

哪位朋友有UDP数据边界方面的资料? 或者链接?
amziwei 2006-01-04
  • 打赏
  • 举报
回复
关于 "避免多组数据同时被放到发送缓冲区中一起发送出去"

不知道这样行不行? 我猜想的!

这种情况通常是在多线程中用send(几乎)同时调用同一套接字下出现的.
如果用临界区把send调用保护起来, 即是说, 一个send 调用完成后再释放这个临界区, 这样不就可以了么?
zhaolaoxin 2006-01-04
  • 打赏
  • 举报
回复
没有这么复杂,客户端每一个recv()对应服务器的一个send(),你只需要区分每一个send()是什么含义即可
amziwei 2006-01-04
  • 打赏
  • 举报
回复
char a[10]="123456789";
char b[10]="abcdefghi";

这两个数组只是为了简化问题

发送之前我会对数据组进行打包的

关键是如何避免多组数据同时被放到发送缓冲区中一起发送出去.
以及出现这种情况后怎么分离这几组数据
RunningYang 2006-01-04
  • 打赏
  • 举报
回复
你说的有一点类似于沾包的现象
不过又不全是

你这种发送方法有点问题
数组之类的数据不能象 VS.NET 里面的串行化一样直接发出去,接收了之后可以直接复原

你要自己加上数据的头
给自己的数据打包

18,356

社区成员

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

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