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]这样。所以无法解密。

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

8329 次点击
所在节点    Go 编程语言
54 条回复
robot1
2019-12-18 15:20:47 +08:00
大学不讲 tcp/ip 吗?
robot1
2019-12-18 15:23:24 +08:00
如果不想处理流,建议上 websocket,加密数据后 base64,
以 text 模式发送。间接达到你们的一发一包的需求
ScepterZ
2019-12-18 15:25:08 +08:00
偷懒的话直接 websocket 就完事了。。如果没什么特殊需求的话
est
2019-12-18 15:26:26 +08:00
粘包警察密切关注此贴(狗头)
no1xsyzy
2019-12-18 15:54:16 +08:00
目前仅仅一个人用作关键词,我觉得还能接受
密切关注中
no1xsyzy
2019-12-18 15:57:22 +08:00
这就是为什么各种协议要么定长要么传长度要么特殊结尾字符
或者使用上述三者的两者甚至三者都用上
honjow
2019-12-18 16:05:51 +08:00
粘包警察密切关注此贴(狗头)
Vegetable
2019-12-18 16:13:18 +08:00
真想弱弱的问一句 HTTPS 他不香吗...
dishonest
2019-12-18 16:14:25 +08:00
@honjow 粘包警察什么梗?
wanguorui123
2019-12-18 16:18:30 +08:00
知道包大小后,网络流读取大小可以通过计数器设置缓冲器读取大小
jworg
2019-12-18 16:19:15 +08:00
@dishonest 起源于这个 https://www.v2ex.com/t/478610 , 其实如果做过 UART 接受数据拆包的话,很好理解的,甚至没觉得有这个问题
ace12
2019-12-18 16:27:14 +08:00
粘包警察密切关注此贴(狗头)
baxtergu
2019-12-18 16:38:50 +08:00
这个属于粘包问题,需要自定义协议,包头定长,包体不定长,然后包头中包含包体的长度。
araraloren
2019-12-18 16:47:45 +08:00
请注意,粘包学家正在赶往此贴。。。
mengzhuo
2019-12-18 18:28:46 +08:00
粘包警察是什么梗……看了那帖子也不清楚
icyalala
2019-12-18 18:34:45 +08:00
粘包学家认为,这肯定是 TCP 的问题,名曰 "粘包"。
粘包警察认为, "粘包" 这个词侮辱了 TCP。
catinsides
2019-12-18 18:46:38 +08:00
@icyalala #36 学到了

粘包警察密切关注此贴(狗头)
hellodudu86
2019-12-18 18:52:18 +08:00
tcp 粘包,我一般是头四个字节写包的长度,然后 tcp 再读取固定长度,最好再判断一下头四字节的长度是否合法。
slanternsw
2019-12-18 18:59:40 +08:00
@shintendo 6 楼已经来了(捂脸)
catror
2019-12-18 19:02:55 +08:00
“粘包警察”是嘲讽普及正确概念的人?

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

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

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

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

© 2021 V2EX