设计问题-通过 TCP 与 Winsock 发送较小的数据段

文章翻译 文章翻译
文章编号: 214397 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

您需要通过 TCP 发送较小的数据数据包,Winsock 应用程序的设计时尤其重要。不会考虑延迟的确认、 Nagle 算法和 Winsock 缓冲的交互的设计方案可以极大地影响性能。本文讨论了这些问题使用几个案例研究和派生的 Winsock 应用程序中有效地发送较小的数据的数据包的建议的一系列。

更多信息

背景

当 Microsoft TCP 堆栈接收数据包中时,200 毫秒延迟计时器熄灭。最终发送 ACK,时延迟计时器重置,并且当接收到下一个数据包时,将启动另一个 200 毫秒延迟。 若要增加在 Internet 和 intranet 应用程序效率,Microsoft TCP 堆栈来决定何时上接收的数据包发送一个 ACK 中使用以下标准:
  • 如果第二个数据数据包接收到延迟计时器过期前,将确认发送。
  • 如果要收到第二个数据数据包并延迟计时器过期前在该 ACK 相同的方向发送的数据在 ACK 是此用数据段,立即发送。
  • 在延迟计时器过期时, 将确认发送。
若要避免出现较小的数据数据包 congest 网络,Microsoft TCP 堆栈默认将合并来自多个发送调用和延迟 ACK 为以前的数据数据包发送之前接收来自远程主机发送的较小的数据缓冲区的使 Nagle 算法。以下是两个例外 Nagle 算法:
  • 如果堆栈已合并数据的缓冲区比最大传输单位 (MTU) 大小,完整大小的数据包而无需等待来自远程主机 ACK 立即发送。一个以太网网络上的 TCP/IP MTU 是可以 1460 字节。
  • 禁用 Nagle 算法,以便在较小的数据的数据包将被传输到远程主机不延迟的情况下应用 TCP_NODELAY 套接字选项。
若要优化应用程序层上的性能,Winsock 应用程序中的副本数据缓冲区发送 Winsock 内核缓冲区的调用。然后,堆栈使用其自己的试探法 (如 Nagle 算法) 来确定何时实际上将在网线上的数据包。您可以更改分配到套接字使用 SO_SNDBUF 选项 (它是 8k 默认情况下) 的 Winsock 内核缓冲区的数量。如有必要,Winsock 可以缓冲大大超过该 SO_SNDBUF 缓冲区大小。在大多数的情况在应用程序中的完成发送仅指示应用程序中的数据缓冲区发送呼叫将被复制到 Winsock 内核缓冲区,并不表示数据已达到网络媒体。唯一的例外是当您禁用通过设置为 0 的 SO_SNDBUF Winsock 缓冲。

Winsock 以指示一个完成发送到应用程序使用下面的规则 (具体取决于调用发送时如何完成通知可能会从一个阻塞调用信号传输事件或调用一个通知函数返回该函数等):
  • 如果该套接字仍然处于 SO_SNDBUF 配额,Winsock 将数据从应用程序发送复制,并指示完成发送到应用程序。
  • 如果套接字已超出了 SO_SNDBUF 配额,并且没有堆栈内核缓冲区中仍然只有一个以前缓冲的发送 Winsock 将数据从应用程序发送复制,并指示完成发送到应用程序。
  • 如果套接字已超出了 SO_SNDBUF 配额,并且没有堆栈内核缓冲区中的多个以前缓冲发送 Winsock 将数据从应用程序发送复制。Winsock 堆栈完成不足,无法发送到放回内 SO_SNDBUF 配额或 $ 只能有一个未完成的发送情况套接字之前并不表示完成发送到应用程序。

案例研究 1

概述:

Winsock TCP 客户端需要将 10000 记录发送到 Winsock TCP 服务器,以将存储在数据库中。记录的大小为 100 个字节长从 20 个字节而变化。为简化应用程序逻辑,设计的是,如下所示:
  • 客户进行仅阻止发送。该服务器进行仅阻止接收。
  • 客户端套接字将在 SO_SNDBUF 设置为 0,以便发生在单个数据段中的每条记录。
  • 服务器调用在循环中接收。在 $ 接收中过帐缓冲区是 200 个字节中,以便可以在一个接收调用中接收的每个记录。

性能:

在测试,过程中,开发人员查找客户端可以只将五条记录,每秒发送到服务器。总 10000 记录在 976 K 字节数据的最大 (10000 * 100 / 1024年),需要向服务器发送到多个半小时。

分析:

因为客户端不会设置 TCP_NODELAY 选项,Nagle 算法将强制等待 ACK,它可以在网络上发送另一个数据包之前 TCP 堆栈。但是,客户端已禁用 Winsock 缓冲通过 SO_SNDBUF 选项设置为 0。因此,在 10000 发送分别调用要发送具有和 ACK'ed。每个 ACK 是延迟的 200 毫秒,因为服务器的 TCP 堆栈上出现以下情况:
  • 当服务器获取一个数据包时,其 200 毫秒延迟计时器熄灭。
  • 以便在 ACK 不能为此,不需要服务器发送回,任何内容。
  • 除非得到确认前一个数据包,客户端将不会发送另一个的数据包。
  • 在服务器上的延迟计时器过期,并在确认发送回。

如何改进:

有两个问题与此设计。第一次,是延迟的计时器问题。客户端需要能够将两个数据包发送到 200 ms.内服务器,因为客户端使用 Nagle 算法,默认情况下,应只需使用默认 Winsock 缓冲并不将 SO_SNDBUF 设置为 0。一旦 TCP 堆栈已合并比最大传输单位 (MTU) 更大的缓冲区,完整大小的数据包而无需等待来自远程主机 ACK 立即发送。

其次,这种设计调用一个发送每个记录的这类小的尺寸。 发送这一大小的小型不是非常有效的。在这种情况下,开发人员可能需要填充到 100 字节的每个记录,并发送 80 记录从一个客户端一次发送呼叫。若要用于服务器知道多少条记录将被发送的总客户端可能需要与包含要遵循的记录数的修补程序大小头开始通信。

案例研究 2

概述:

Winsock TCP 客户端应用程序打开两个连接与 Winsock TCP 服务器应用程序提供股票报价服务。第一个连接用作命令通道发送到服务器的股票代码。第二个连接用于为数据信道接收股票报价。这两个连接建立后,客户端向服务器通过命令通道发送股票符号,并等待要通过数据通道回来了股票报价。仅在收到第一个股票报价之后下一个股票代码请求发送到服务器。在客户端和服务器不要设置 SO_SNDBUF 和 TCP_NODELAY 选项。

性能:

在测试,过程中,开发人员查找客户端只可以得到每秒的五个引号。

分析:

这种设计只允许一个未完成的股票报价请求一次。通过命令通道 (连接) 到服务器发送第一个股票代码并响应立即发送回从服务器到客户端通过数据通道 (连接)。然后,客户端立即发送第二个股票代码请求并发送返回紧靠在发送调用请求缓冲区复制到 Winsock 内核缓冲区。但是,客户端 TCP 堆栈不能立即因为通过发送第一个命令通道未得到确认尚未从其内核缓冲区中发送该请求。200 毫秒延迟在计时器后过期的服务器命令信道,为第一个符号请求确认恢复到客户端。然后,第二个引号请求是成功发送到服务器后 200-ms.第二个股票符号的报价单恢复立即该数据的通道,因为这次在客户端数据信道,延迟计时器已过期的延迟。以前的报价单响应 ACK 是由服务器接收的。(请记住在客户端无法发送第二个的股票报价请求 200-ms 因此提供的延迟计时器过期并向服务器发送一个 ACK 在客户端上的时间。如此一来,客户端获取第二个引号响应并可以发出另一个报价单请求即属于相同的周期。

如何改进:

两个连接 (通道) 设计不需要在此处。如果只有一个连接用于股票报价请求和响应,可在报价单响应此报价单请求的 ACK,并将其立即回来。多路以进一步提高性能,客户端可以"传输"股票报价的多个请求到服务器的一个发送呼叫和多路服务器可能还"传输"多个报价单响应到客户端发送调用。由于某些原因确实需要两个单向通道设计是否双方都应设置 TCP_NODELAY 选项,以便不必等待上一个数据包的 ACK 立即发送小数据包。

建议:

尽管这些两个案例研究 fabricated,它们帮助说明了一些最坏的情况。涉及到大量的小数据段的应用程序的设计时将发送并 recvs,您应考虑以下准则:
  • 如果不,的数据段是时间关键,应用程序应合并这些到一个较大数据块中要传递给发送调用。可能会被复制到 Winsock 内核缓冲区发送缓冲区是缓冲区不应太大。稍少于 8k 通常会有效。只要 Winsock 内核获取块大于 MTU,则它将发送出多个大的数据包,并与任何剩余的最后一个数据包。除了在最后一个数据包的发送侧边将不会被命中由 200 毫秒延迟计时器。在最后一个数据包如果它正好是一个奇数数据包是仍受限于延迟的确认算法。如果在发送最终堆栈获取另一个块大于 MTU,它仍可以绕过 Nagle 算法。
  • 如有可能避免使用单向数据流的套接字连接。单向套接字上的通信是更方便地在 Nagle 受影响和延迟确认算法。如果通信后面的请求和响应流,您应使用单个的套接字执行发送并且 recvs,以便可以将该确认此在响应。
  • 如果要立即发送的所有较小的数据段,设置 TCP_NODELAY 发送端上的选项。
  • 除非要保证完成发送由 Winsock 指示时,将数据包发送在网线上您不应将该 SO_SNDBUF 设置为零。事实上,默认 8k 缓冲区已 heuristically 确定适用于大多数情况下,不能更改它除非进行了测试您新 Winsock 缓冲区设置可使您更好的性能比默认值。此外,SO_SNDBUF 设置为零是很有益的应用程序的执行大容量数据传输。甚至,获得最高的效率,应使用它连同双缓冲 (在任何给定的时间多个未完成发送) 然后重叠的 I/O。
  • 如果数据提交不一定能保证,请使用 UDP。

参考

请为延迟确认和 Nagle 算法有关的详细信息请参阅以下内容:

Braden,键。 [1989] RFC 1122、 Internet 主机--通讯层 Internet 工程任务的要求强制。

属性

文章编号: 214397 - 最后修改: 2005年7月11日 - 修订: 3.1
这篇文章中的信息适用于:
  • Microsoft Platform Software Development Kit-January 2000 Edition
关键字:?
kbmt kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock KB214397 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 214397
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com