发送流终止字节以指示 TCP 流结束
Posted
技术标签:
【中文标题】发送流终止字节以指示 TCP 流结束【英文标题】:Sending stream terminating bytes to indicate end of TCP stream 【发布时间】:2021-09-20 09:26:47 【问题描述】:例如,我希望通过 TCP 传输某些内容,例如文件共享(读取文件的字节数)或进程的输出(stdin、stderr、stdout)通过使用CreateProcess 或_popen 的管道.我将无法计算流输出的字节大小。如果我要发送一组特定的特殊字符来指示流已结束以由服务器/客户端解析,这是否实用且安全?
【问题讨论】:
您可以在发送文件之前计算大小并将此信息提供给接收方。为什么如此重要?您是否发送整个文件,为什么不将其拆分成块?每个块的大小都等于块大小,除了最后一个。每个数据包都是SIZE|bytes
是的,我明白了,但是通过管道的流呢?
你怎么能排除你的流包含你选择指示结束的任何字节?
【参考方案1】:
如果我要发送一组特定的特殊字符来指示流已结束以由服务器/客户端解析,这是否实用且安全?
如果文件的内容可以是任意二进制数据,那么,不,这本身并不是一种“安全”的方式,因为您使用的“特定的特殊字符集”可能会出现在文件的某处,因此它们将通过连接发送,而接收者会认为文件已经结束,而实际上并没有结束。
(我说这不是“安全的”,这意味着它不能保证正确传达文件的方式,因为不清楚您所说的“实用”或“安全”是什么意思。从什么开始安全?有没有一些攻击者给你文件传输,所以他们可以用恶意方式制作它们?如果你所有的文件都知道只包含纯文本 ASCII 字符,你可以“安全地”使用非 ASCII 字符作为标记。)
有无数种方法可以制作协议来发送任意数据。您可以先发送长度(尽管随后您需要决定使用多少位来表示长度,或者设计一些协议来发送任意长度的位)。您可以以 512 字节的块的形式发送数据,然后首先发送每个块的长度。只要该长度为 512 字节,就意味着相同数据的另一个块即将到来。一旦长度小于 512 字节(包括 0),则表示这是数据的最后一个块。您可以将数据作为带引号的字符串发送,以"
开头,然后是数据的字节,除了数据中的每个"
实际上发送为\
然后"
和每个\
数据以\
和\
发送,然后数据的结尾由"
指示(前面没有转义它的\
)。
【讨论】:
你很好地解释了一些细微差别。我想做的一个补充是,潜在地添加加密,添加校验和、摘要哈希或签名来验证数据完整性会更“安全”。 如何在 C 中转义引号字符或取消转义?是否有为此的标准库函数?还是我必须自己动手做这个功能? C 是否会在通过 TCP 发送之前自动转义字符,如果是这样,我如何在接收端取消转义字符?以上是关于发送流终止字节以指示 TCP 流结束的主要内容,如果未能解决你的问题,请参考以下文章