有什么方法可以知道在发送之前将在 TCP 上发送多少字节?
Any way to know how many bytes will be sent on TCP before sending?
我知道 Linux TCP 服务器中的 ::send
可以限制有效载荷的发送,因此 ::send
需要多次调用,直到整个有效载荷已发送。
即有效载荷为 1024 字节
sent_bytes = ::send(fd, ...)
其中 sent_bytes
只有 256 字节,因此需要再次调用。
有什么方法可以在发送前准确知道可以发送多少字节?如果套接字将允许整个消息,或者消息将被分割成多少?
示例案例
2条消息通过::send()
在同一个tcp客户端上被不同的线程同时发送到同一个套接字。在某些消息很大的情况下,需要对 ::send()
进行多次调用,因为并非所有字节都在初始调用时发送。因此,继续循环解决方案,直到发送完所有字节。该循环是互斥的,因此可以看作是线程安全的,因此每个线程都必须在另一个线程之后执行发送。但是,我担心的是,因为 Tcp 是一个流,客户端将收到每条消息的片段,我想如果我知道一次发送多少字节,我可以在客户端重建消息.
虽然对::send()
的调用是顺序完成的,但是字节流是否仍然是混合的?
实际上,这是否会发生:
- 服务器端
- 消息 1:“CiaoCiao”
- 消息 2:“HelloThere”
- 客户端
- 收到消息:“CiaoHelloCiaoThere”
Although the call to ::send() is done sequentially, is the any chance that
the byte stream is still mixed?
当然可以。不仅有这样的机会,而且在某一时刻几乎是确定无疑的。它会在某一时刻发生。保证。
sent to the same socket by different threads
有必要在此级别处理同步,方法是使用每个线程在发送其消息之前锁定的互斥锁,并仅在发送整个消息后解锁它。
不用发送,这会留下一个可能性,即 blocked/hung 套接字将导致单个线程锁定此互斥量过长的时间,直到套接字超时并且您的执行线程结束处理失败的 send()
或 write()
,以任何它现在正在做的方式(当然,你正在检查 send/write 的 return 值,并处理异常适当的条件)。
没有单一的、cookie-cutter、paint-by-numbers 解决方案适用于任何情况、每个程序,需要做这样的事情。每个最终解决方案都需要根据每个项目的独特要求和目的进行定制。只有一种可能性是处理所有套接字 input/output 的专用执行线程,并且所有其他执行线程将它们的消息发送到套接字线程,而不是直接写入套接字。这将避免 all 执行线程被挂起的套接字楔入,以增加内存为代价,它保存所有未发送的数据。
但这只是一种可能的方法。可能的替代解决方案的数量没有限制。您需要确定哪种基于 logic/algorithm 的解决方案最适合您的特定程序。没有操作 system/kernel 级别指示可以为您提供关于套接字上的 send()
或 write()
调用数量的任何类型的保证。
我知道 Linux TCP 服务器中的 ::send
可以限制有效载荷的发送,因此 ::send
需要多次调用,直到整个有效载荷已发送。
即有效载荷为 1024 字节
sent_bytes = ::send(fd, ...)
其中 sent_bytes
只有 256 字节,因此需要再次调用。
有什么方法可以在发送前准确知道可以发送多少字节?如果套接字将允许整个消息,或者消息将被分割成多少?
示例案例
2条消息通过::send()
在同一个tcp客户端上被不同的线程同时发送到同一个套接字。在某些消息很大的情况下,需要对 ::send()
进行多次调用,因为并非所有字节都在初始调用时发送。因此,继续循环解决方案,直到发送完所有字节。该循环是互斥的,因此可以看作是线程安全的,因此每个线程都必须在另一个线程之后执行发送。但是,我担心的是,因为 Tcp 是一个流,客户端将收到每条消息的片段,我想如果我知道一次发送多少字节,我可以在客户端重建消息.
虽然对::send()
的调用是顺序完成的,但是字节流是否仍然是混合的?
实际上,这是否会发生:
- 服务器端
- 消息 1:“CiaoCiao”
- 消息 2:“HelloThere”
- 客户端
- 收到消息:“CiaoHelloCiaoThere”
Although the call to ::send() is done sequentially, is the any chance that the byte stream is still mixed?
当然可以。不仅有这样的机会,而且在某一时刻几乎是确定无疑的。它会在某一时刻发生。保证。
sent to the same socket by different threads
有必要在此级别处理同步,方法是使用每个线程在发送其消息之前锁定的互斥锁,并仅在发送整个消息后解锁它。
不用发送,这会留下一个可能性,即 blocked/hung 套接字将导致单个线程锁定此互斥量过长的时间,直到套接字超时并且您的执行线程结束处理失败的 send()
或 write()
,以任何它现在正在做的方式(当然,你正在检查 send/write 的 return 值,并处理异常适当的条件)。
没有单一的、cookie-cutter、paint-by-numbers 解决方案适用于任何情况、每个程序,需要做这样的事情。每个最终解决方案都需要根据每个项目的独特要求和目的进行定制。只有一种可能性是处理所有套接字 input/output 的专用执行线程,并且所有其他执行线程将它们的消息发送到套接字线程,而不是直接写入套接字。这将避免 all 执行线程被挂起的套接字楔入,以增加内存为代价,它保存所有未发送的数据。
但这只是一种可能的方法。可能的替代解决方案的数量没有限制。您需要确定哪种基于 logic/algorithm 的解决方案最适合您的特定程序。没有操作 system/kernel 级别指示可以为您提供关于套接字上的 send()
或 write()
调用数量的任何类型的保证。