Go 怎么避免连续读取过多字节(TCP)

2019-12-18 14:19:51 +08:00
 dying4death

简单地说,服务端将一段数据 AES 加密,客户端接收到数据后解密。

伪代码展示:

// 从输入流里读取加密过的数据,解密后把原数据放到 bs 里
func (secureSocket *conn) DecodeRead(bs []byte) (data []byte, err error) {

	n, err := secureSocket.Read(bs)
	if err != nil {
		fmt.Println("decode read: ", err)
		return
	}
	fmt.Println("decode read: ", bs)
	fmt.Println("decode read count: ", n)
	data, err = secureSocket.Cipher.decode(bs[:n])

	return
}

// 把放在 bs 里的数据加密后立即全部写入输出流
func (secureSocket *SecureTCPConn) EncodeWrite(bs []byte) (int, int, error) {
	
	data, err := secureSocket.Cipher.encode(bs)
	if err != nil {
		return
	}
	writedCount, err := secureSocket.Write(data)
	if err != nil {
		return 0, 0, err
	}
	return writedCount, len(data), nil
}

环境使用 Mac,本地测试一切正常。加解密以及数据转发等都能正常进行。然后将服务端代码打包成 linux 执行文件丢到 VPS 中运行,出现了客户端解密失败,发现是因为客户端读取数据时,读取了多段字节,导致无法解密。

比如说就是,服务端依次发送,[1 2 3],[4 5 6]两端加密后的字段,客户端读取了[1 2 3 4 5 6]或者其他可能,并不是读取[1 2 3],然后[4 5 6]这样。所以无法解密。

因为服务端也是转发的数据,客户端无法确知加密后完整的一段数据长度时多少?

8340 次点击
所在节点    Go 编程语言
54 条回复
newtype0092
2019-12-18 19:07:20 +08:00
@mengzhuo 就是有些人用水龙头接水洒了一地,冥思苦想后觉定用杯子一杯一杯接,然后把这种方法整理成册大肆宣传,声明自己解决了水龙头的一大缺陷。
lingxi27
2019-12-18 19:07:25 +08:00
粘包警察密切关注此贴(狗头)
zhujinliang
2019-12-18 19:12:52 +08:00
方法 1. 处理“粘包🐶”
方法 2. 使用 CFB 之类的流加密模式
mosfet
2019-12-18 19:18:02 +08:00
你可以参考 MODBUS 协议,增加起始符和停止符
wanglufei
2019-12-18 20:23:43 +08:00
@maichael 以前面试就该问题差点和面试官干起来
hzwjz
2019-12-18 21:26:09 +08:00
粘包警察密切关注此贴(狗头)
cs419
2019-12-18 21:53:12 +08:00
粘包问题大家都说了

不过描述中 先是自己加密解密
完了又说不是自己加密的 。。。
back0893
2019-12-18 22:28:11 +08:00
粘包吧.
tcp 定义 header+data
header 作为 data 的长度
alphatoad
2019-12-19 04:26:08 +08:00
用 stream cipher 解决你的所有问题
神 tm 粘包
liuguang
2019-12-19 09:32:57 +08:00
粘包问题,定好传输协议就不会这样了
Mohanson
2019-12-19 11:47:41 +08:00
TCP 是流协议,只有 UDP 才有包的概念。所谓粘包…就是早年国内一些不了解 TCP 原理的人发现一个自己脑袋无法理解的现象后造出来的概念… 记住了,讲这个词会被人笑话的
lxz6597863
2019-12-19 15:35:19 +08:00
TCP_NODELAY 可能是这个影响的
但是还是建议自己定个包头格式
nnnToTnnn
2019-12-19 15:38:34 +08:00
@zappos #6 什么叫做 TCP 粘包? 那特么就是自己程序没写好!!!!!!
wlgq2
2019-12-26 14:40:45 +08:00
粘包警察虽迟,但一定会到:)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/630159

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX