[问题] Socket 传送大资料时会与后续资料串起来

楼主: jakeasa123 (啊斑斑)   2021-03-26 16:24:38
小弟先前写了几个小程式,
主要透过 socket 来达成连线和资料的传输。
在当时就有遭遇如同标题的问题,
例如说从 server 这一方发送:
 conn.sendall('执行 A'.encode('utf-8'))
 conn.sendall('执行 B'.encode('utf-8'))
连续发送数个资料时,
client 方就很容易接收成:
 执行 A执行 B
这样子期望上要分开却串在一起情形。
后来的做法是在发送时加上固定的字尾作为辨识,
例如小弟加了 DataEnd,
因此上面的例子中,
client 方会接收成:
 执行 ADataEnd
 执行 BDataEnd
当然偶尔还是会串在一起变成“执行 ADataEnd执行 BDataEnd”,
但因为有辨识用的字尾在里面,
使用 find 这类函数就可以把接收到的资料切开处理。
这一次的问题则是起于我想要传送一个较大的资料,
3 分钟左右的影片、图片或文件档都好。
上述的解决办法虽然能解决串起来的问题,
但当接收的资料较大时,
每次 client 执行 recv 完,
就得跑一次 find,
变得 30 MB 的档案在 client 端要花上好几十分钟才能接收完。
一开始想说会不会是网络的问题,
但把 client 的程式码大多都拔掉到只剩下接收功能时,
不到一分钟就能把同样的档案接收完成。
因此,
想来这里向各位前辈请教,
该如何解决这样的窘境?
目前暂时的解决法是借由 thread 设置了两组 server 与 client:
 第一组 server 与 client 只负责传送简短的资料或命令
 第二组 server 与 client 只负责传送较大档案的资料
并在第二组 server 每次 sendall 后加入 10 秒的 sleep,
避免与下一个档案串在一起。
先谢谢各位前辈阅览此问了。
作者: james732 (好人超)   2021-03-26 21:52:00
tcp会帮你合并或分割,一个做法是加上header写长度
作者: cuteSquirrel (松鼠)   2021-03-27 00:20:00
header里面放后面payload的长度,当buffer收到足够长的rawdata,就切割/解码一次,然后buffer清旧资料再继续下个循环,如此反复操作一个小例子:server: https://pastebin.com/wRxgBigRclient: https://pastebin.com/BycG0ZDThttps://i.imgur.com/px9Io12.png就像一楼说的那样,关键字:tcp sticky packet
楼主: jakeasa123 (啊斑斑)   2021-03-28 12:44:00
谢谢各位提供的资料和关键字!
作者: cuteSquirrel (松鼠)   2021-03-29 00:20:00
不客气~

Links booklink

Contact Us: admin [ a t ] ucptt.com