Delay Between TCP Response Packets Generated by ISAPI on IIS

ID: Q240146


The information in this article applies to:
  • Microsoft Internet Information Server versions 1.0, 2.0, 3.0, 4.0
  • Microsoft Internet Information Services version 5.0


SUMMARY

A delay can occur between two TCP response packets in a Keep-Alive connection. It does not matter whether ISAPI is invoked with GET or POST.


MORE INFORMATION

To prevent wasted space in TCP packets, the IIS socket attempts to wait until the data area of a packet is full (1460 bytes for Ethernet TCP/IP) before sending it out (Nagling). TCP will wait up to 200 ms before it sends a partially full packet.

The behavior mentioned above takes place with all versions of IIS. However, in IIS 5.0, the HSE_IO_NODELAY flag can be passed to WriteClient calls to turn off Nagling for the duration of the call. Add the HSE_IO_NODELAY flag to all WriteClient calls to force ISAPI to never "nagle." Synchronous WriteClient calls would look similar to the following:


pECB->WriteClient(
	pECB->ConnID,
	pBuffer,
	&cbBuffer,
	HSE_IO_SYNC | HSE_IO_NODELAY
	); 
Please note that this workaround applies only to IIS 5.0. This behavior is by design.

The IIS socket uses Nagle algorithm to maximize the space utilization in TCP packets. TCP tries to wait until the data area of the packet is full before sending out the packet, and it will wait up to 200 ms before it sends a partially full packet. If the socket connection is closed, then all outstanding data is sent.

With a Keep-Alive connection, the client needs to have some way of knowing when the response is complete so that it can correctly process the response. IIS uses the Content-Length header to tell the client how many bytes to expect, or it can tell the client that its done after sending the response by closing the connection. Given these facts, here are the two scenarios:

Scenario 1 (no Content-Length):
  1. The client sends a Keep-Alive HTTP request.


  2. ISAPI sends a response that does not support Keep-Alive (no content-length) and is less than 1460 bytes.


  3. The TCP stack on the server waits for up to 200 ms for more data to fill the packet.


  4. The server closes the connection as soon as ISAPI returns and TCP stops waiting.


Scenario 2 (with content-length):
  1. The client sends a Keep-Alive HTTP request.


  2. ISAPI sends a response that does support Keep-Alive (with Content-Length) and is less than 1460 bytes.


  3. The TCP stack on the server waits for up to 200 ms for more data to fill the packet.


  4. IIS does not close the connection when ISAPI returns, so TCP ends up waiting the full 200 ms before sending.


For more information, please see the following:
Q126716 Poor TCP/IP Performance When Doing Small Sends
Q214397 Design Issues - Sending Data Segments Over TCP w/Winsock
RFC 2068, Hypertext Transfer Protocol - HTTP/1.1

Additional query words:

Keywords : kbGrpInetServer
Version : winnt:1.0,2.0,3.0,4.0,5.0
Platform : winnt
Issue type : kbhowto


Last Reviewed: February 2, 2000
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.