【问题标题】:General ? - The maximum number of segmented/ split bytes sent over a connection using TCP Protocol?一般的 ? - 使用 TCP 协议通过连接发送的最大分段/拆分字节数?
【发布时间】:2011-12-05 20:38:28
【问题描述】:

只是想问一下从服务器和客户端来回发送数据时的字节限制应该是多少通过连接发送的分段字节的大小?

因此,如果我将缓冲区大小设置为 3072 字节以从客户端发送到服务器,并且在从服务器向客户端发送数据时也是如此,那么这些字节是如何分段的?以及通过连接发送的最大字节数是多少,这样字节就不会被分段?

【问题讨论】:

  • nagle 是启用还是禁用?
  • which 字节数取决于这些东西吗?您是否关心单个数据包?你真的需要吗?
  • @MarcGravell,我如何在 java 中启用或禁用 nagle?
  • @JonSkeet,在堆栈溢出和在线文章的帮助下,我开发了一个现场音频广播。因为音频格式产生 174600 字节,所以在服务器之间发送和返回的字节数太大了。所以我所做的是拆分数据并像这样发送字节,我将这些拆分字节设置为 3072。我问这个问题的原因是,当我将数据发送到分段时,我设置的字节越多,音频的质量就越好产生。 .感谢您的回复。
  • @redoc01: 174600 字节不是太大,无法通过 TCP 连接发送。但它分成数据包。这就是问题所在 - 不清楚您在哪里谈论数据包以及您在哪里谈论 TCP 作为流协议。

标签: java php .net sockets tcp


【解决方案1】:

TCP 不保证客户端用一个发送命令发送的字节数与服务器用一个接收命令接收的字节数相同。 TCP 是基于流的,意味着它将连接视为字节流而不是消息流。

发送这个(两次发送):

  1. “你好”
  2. “世界”

可以接收为:

  1. “HelloWorld”

或者。

  1. “他”
  2. “洛”
  3. “世界”

或任何其他组合。

因此,您需要能够检测一条消息何时结束,而下一条消息何时开始。两种最常见的方法是使用包含长度的消息头或后缀(如换行符)来检测消息的结尾。

更新

TCP 不应该用于音频流恕我直言。原因是 TCP 保证传送所有发送的数据包。因此,如果 TCP 检测到一个数据包没有到达,它将阻塞所有排队的数据包,直到失败的数据包到达。

在流式传输音频时,所有数据包都到达并不重要,一个丢失的数据包不会对声音产生太大影响。由于网络协议会尝试传递所有数据包,因此让音频流完全停止比让音频流完全停止要好一些。

【讨论】:

  • 在堆栈溢出和在线文章的帮助下,我开发了一个现场音频广播。因为音频格式产生 174600 字节,所以在服务器之间发送和返回的字节数太大了。所以我所做的是拆分数据并像这样发送字节,我将这些拆分字节设置为 3072。我问这个问题的原因是,当我将数据发送到分段时,我设置的字节越多,音频的质量就越好产生。是的,当字节段完成时,我确实会发送一条消息。感谢您的回复。
  • 酷,我会尝试 UDP,我打算尝试这种方法,但是当我浏览示例时,其中一篇文章建议使用 TCP,但我相信你是正确的。
  • 为什么不使用现有的协议/库而不是自己发明?
  • 就是这样,我想使用一些免费的东西,发现 red5 媒体服务器是解决方案,但我什至无法让教程工作。我在 java 中设置了环境并试图让测试应用程序工作,但我尝试了 2 天,我受够了,决定自己做。我宁愿使用现有的图书馆,因为我没有时间。但是我花在试图让现有图书馆工作上的时间太长了。加上像 Spencer Ruport 解释的那样,自己动手做是一种很好的学习体验。如果我没有 den 就不会获得知识很棒的网站。
  • 我测试了 UDP 通过连接发送声音,很多数据包丢失,听不到声音,你认为我应该坚持使用 TCP 吗?
【解决方案2】:

在连接的一端和另一端之间将有一个关于MTU 大小的握手,并且根据这个大小和与TCP 一起使用的协议。一个数据包将发送大量数据。

但是,如果您不使用低级 API,则将数据拆分/合并为数据包是由您的协议栈完成的。

【讨论】:

    【解决方案3】:

    如果您将 3000 字节写入 TCP 套接字,您将在接收端收到 3000 字节。 TCP 对其上面的协议没有规定的最大字节数。从 TCP 到 IP 到堆栈再到下面的协议,是的,存在限制,但您的应用程序不必担心这一点。将以太网帧分割和重新组装成 ip 数据报等......将在您背后照顾。

    但是,您必须担心应用程序级别的协议,即基于 TCP 的协议。尽管 TCP 将传送所有 3000 个字节,但不能保证一次调用 recv(或任何等效的 java/php 语言)将立即返回所有 3000 个字节。在从套接字读取所有 3000 个字节之前,您可能需要多次调用它。

    查看这里了解更多信息:

    How to know when you finish receiving a TCP stream?

    【讨论】:

      【解决方案4】:

      除非您正在编写 TCP 协议包装器,否则您提出这个问题的事实很好地表明您正在处理您试图错误解决的任何问题。您指定的语言中的 TCP 实现充当抽象,应该使这个问题的答案完全无关紧要。

      请参阅此处了解我对有关数据包重组的类似问题的回答: What's the best way to monitor a socket for new data and then process that data?

      【讨论】:

        猜你喜欢
        • 2011-02-18
        • 2018-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多