![]() |
|
| << Previous | Index | Next >> | |
| | |
Once you have a TCP/IP application coded and working, it is worthwhile to tune the application to get the best possible performance. There is usually a trade-off between performance and memory usage. If more memory is available, you can specify larger data buffers to improve overall performance. Conversely, if performance is already adequate, you can reduce buffer sizes to make room for more application functionality.
Some performance improvements can be made without large increases in memory usage. To make these improvements, you will need to understand how TCP, IP and the properties of the network work and interact. This is a complex subject, which is well covered in various texts. This section concentrates on the characteristics of the Dynamic C TCP/IP stack. Most of the discussion is centered around Dynamic C version 7.30, but many of the principles apply to earlier releases. The discussion also concentrates on TCP. UDP is also mentioned where appropriate, however UDP performance is mainly determined by the application so there are not as many tuning controls available in the Dynamic C libraries for tuning UDP performance.
The type of application has a large bearing on the performance tuning options which will be most appropriate. Here are some basic types of application which have different performance requirements:
Bulk Loader: an application which periodically uploads large amounts of data (such as a log) to a server
Casual Server: one which just needs to process occasional commands which come in from the network. This includes "interactive" servers such as telnet.
Master Controller: one which sends short data bursts to a number of "slave" controllers, which must be sent and processed in a timely manner
Protocol Translator: accepts stream of data, perhaps serial, and converts to a TCP data stream, or vice-versa
All these application types have different requirements for the basic properties of a communications channel, namely bandwidth, throughput and latency.
The bandwidth of a channel is the maximum sustained rate of end-to-end data transmission, in bytes per second. A full-duplex channel has the same bandwidth in each direction, independent of data traffic flowing in the opposite direction. In a half-duplex channel, the total bandwidth is divided between both directions. Ethernet is usually half-duplex in that an Ethernet chip cannot send and receive at the same time, however some types of Ethernet can run full-duplex.
The throughput of a channel is related to bandwidth, but is used to express the amount of useful data that can be transmitted through the channel in a fixed (specified) amount of time, using a practical transport protocol (i.e., a protocol which adds some overhead to each message). Throughput generally improves as the bandwidth rises, and as the time interval increases. Throughput is always less than bandwidth for finite time intervals or practical protocols, since there is usually some overhead to establish the connection in the first place, as well as overhead during the transmission itself.
The latency of a channel can have several definitions. For our purposes, it is the minimum possible time delay between sending of a message, its receipt by the other end, and the reception of a reply; in other words, the round-trip-time (RTT). On electrical and radio channels, the latency is related to the physical length of the link and the speed of light. On channels which are more complex than a simple electrical connection, there may also be intermediate nodes which buffer the data being transmitted: this can add delays which are much larger than the speed of light between the end nodes.
Note that round-trip times are important for most communications protocols: not only do we want to send data, but we also want to receive an acknowledgment that the other end received the data.
Some examples of real networks may be helpful here. Note that the values given for RTT are approximations since they depend on the length of the connection, the sizes of packets sent, or intermediate nodes. Throughput is specified for an infinite time interval, assuming TCP over IP with 600 bytes of data per packet, and no data in the acknowledgment The RTT figure assumes the same size packets.
Table 4.1 Channel Characteristics for Selected Networks
Local 10Base-T Ethernet PPP over 8N1 serial (57.6k) PPPoE over 1.5Mbit DSL The above table does not count any delay in the host which generates the response, nor any delay passing through the Internet. These represent minimum possible RTTs.
4.1 DBP and Sizing of TCP Buffers
An important quantity derived from the above is known as Delay-Bandwidth Product (DBP). As the name suggests, this is the product of bandwidth and RTT, and has units of bytes. It represents the maximum amount of data (and overhead) that can exist "in the network" at any point in time. This number has implications for sizing of TCP socket buffers. The DBP for local 10Base-T Ethernet is about 750 bytes. For local Ethernet connections, the DBP is about the same as the packet size of the transmitted data. For wider area networks that have significant propagation delays, the DBP can increase substantially. For example, satellite links can add several 100's of milliseconds to the RTT. If the bandwidth is high enough, the DBP can exceed the packet size by orders of magnitude. This means that several packets may be in transit at the same time.
The DBP is important for TCP connections. This is because TCP is able to transmit a large number of packets into the network without having to wait for an acknowledgement for each one. Similarly, a TCP can receive a large number of packets without necessarily acknowledging them all. In fact, TCP only has to acknowledge the most recent packet; the sender can assume that all earlier packets are implicitly acknowledged.
How does all this apply to sizing of TCP socket buffers? It basically means that there is little point in making the buffers (both transmit and receive) larger than the expected maximum DBP of the communications channel. For connections which are expected to traverse the Internet, you may need quite large buffers. For local Ethernet only, the buffers need not be larger than, say, two packets.
The maximum packet size is a compromise between performance and memory usage. The largest packet supported by
dcrtcp.libis 1500 bytes, which is dictated by the limits of Ethernet. Dynamic C's default packet size is 600 bytes. Using large packet sizes improves performance for bulk data transfer, but has little effect for interactive traffic. Performance is improved for large packet sizes mainly because there is less CPU overhead per byte. There is a roughly fixed amount of CPU time required to process each packet. This is obviously better utilized if there are a large number of bytes per packet.When using Ethernet, the Rabbit processor is limited in its overall TCP/IP throughput by CPU power. 10Base-T Ethernet is capable of 1MB/sec for TCP sockets1, however the Rabbit 2000 running at 21MHz will only be able to transmit at about 270kB/sec when sending 1500 byte packets. Receive rate is slightly slower at about 220kB/sec. This scales approximately linearly with respect to CPU clock speed as well as application use of the CPU. In short, current Rabbit-based boards cannot use the full bandwidth of a local Ethernet link.
The situation changes for PPP over serial. In this case, the serial port bandwidth is less than the rate at which packets can be generated or received. Also, PPP is typically used to access peers over the Internet, so there may be a much larger DBP than for a pure point-to-point link. For PPP serial links, smaller packet sizes, e.g. 256 bytes, are satisfactory for bulk data transfers without impacting interactive traffic, should that be required. Socket buffer sizes should be determined based on the expected Internet RTTs, which may be 1 second or more. For a 57.6kbps serial link, the DBP is 5000 bytes for 1 second RTT, thus the socket buffers should be about this size for receive and transmit.
TCP is adaptive to changing network conditions. For example, the RTT can vary considerably at different times of day, and communication channels can become congested. TCP is designed to cope with these conditions without exacerbating any existing problems, however socket buffer and packet sizes are usually constants for the application so they need to be selected with due consideration to the most common conditions.
4.2 TCP Performance Tuning
TCP is a well-designed protocol, and provides nearly optimum performance over a wide range of conditions. Obtaining the best possible performance requires the application to co-operate with TCP by setting the correct options if the defaults are not optimal, making the most efficient use of the socket API functions, and providing appropriate memory and CPU resources.
The available performance-related options are:
Sizing of buffers was discussed in the previous section. The following sections discuss the other performance controls.
4.2.1 The Nagle Algorithm
The Nagle algorithm is an option for TCP sockets. It modifies the transmit processing for a socket, but has no effect on receive processing. The TCP/IP library allows Nagle to be applied on a per-socket basis.
Most applications should leave the Nagle algorithm enabled for each TCP socket, which is the default. This provides the best utilization of bandwidth, since it prevents many small packets from being sent where one big packet would be preferable.
The main reason to override the default, and disable the Nagle algorithm, is for applications that require the least possible delay between writing data to the socket, and its receipt by the peer application. This comes at the expense of efficiency, so you should carefully consider whether the application really requires the slight reduction in delay.
When Nagle is turned off, using the macro
tcp_set_nonagle(&socket), transmit processing is changed so that TCP tries to transmit a packet for each call of a socket write function such assock_fastwrite().If Nagle is on (which is the default state or can be set using
tcp_set_nagle(&socket)) a new packet will only be sent if there is no outstanding unacknowledged data. Thus, on a slow network where acknowledgements from the peer take a substantial amount of time to arrive, fewer packets will be sent because there is a greater chance that there is some unacknowledged data.The difference may be illustrated by the following example: suppose that a TCP socket connection is currently established and quiescent (i.e., there is no outstanding data to be acknowledged; everything is up-to-date). The network round-trip-time is 550ms. The application writes ten single characters to the socket, at 100ms intervals each. With Nagle turned off, ten packets will be sent at approximately 100ms intervals. Each packet will contain a 40-byte header (IP and TCP) with a single byte of data. A total of 410 bytes will be sent. With Nagle on, the first character written at time zero will cause a 41-byte packet to be sent. The acknowledgment of this first packet will not arrive for another 550ms. In the meantime, the application writes an additional 5 characters at 100ms intervals. Since there is outstanding unacknowledged data (the first character) these characters are not sent immediately. They are buffered, waiting for an acknowledgment from the peer. When the first character's acknowledgment comes in at 550ms, there is no outstanding unack'ed data; the additional 5 characters have not yet been sent so they do not count as unack'ed data. Now the TCP stack will send the 5 additional characters in a single packet at approximately t=550ms. While that packet is in transit, 4 more characters are written by the application. Again, these characters will be buffered since characters 2 through 6 have not been acknowledged. Only when the next acknowledgment is received will these 4 characters be sent. The total number of packets sent is 3, with 1, 5 and 4 bytes of data. This translates to 130 bytes in total.
Obviously, the total number of bytes transmitted, including overhead, is far less when Nagle is used (130 compared with 410 bytes). One can also examine how this looks from the point of view of the peer.
In the non-Nagle case, each character is received 275ms after it was transmitted (we assume that the one-way trip is half of the RTT). The last character is received at t=1175ms (with the reference t=0 taken as the first character transmission time). The acknowledgment of the last character, which completes the transaction, is received at t=1400ms.
In the Nagle case, the last character is received at t=1375 and the final acknowledgment at t=1650. In this example, the peer received all 10 characters 200ms later when Nagle was used.
It can be seen that at a slight cost in increased delay, a great saving in total data transmission was made. If the above example was extended to hundreds or thousands of characters, then the additional delay would remain constant at a few hundred ms, whereas the network bandwidth would be better utilized by a factor approaching five!
In conclusion, leave Nagle on unless you absolutely must have the lowest delay between transmission and reception of data. If you turn Nagle off, ensure that your application is disciplined enough to write the largest blocks it can. For example, if you have to send an 8-byte value (as a unit), construct the full 8 bytes as a single block then write them all in a single
sock_fastwrite()call, rather than callingsock_fastwrite()with two 4-byte calls or, worse, 8 single byte calls.A useful alternative to turning Nagle off is to control packetization using calls to
sock_flush(),sock_noflush()andsock_flushnext(). These functions allow the application fairly fine control over when TCP sends packets. Basically,sock_noflush()is used to set a "lock" on the socket that prevents TCP from sending packets containing new data. Aftersock_noflush(), you can callsock_fastwrite()or other write functions. The new data will not be sent until the socket is "unlocked" with a call tosock_flush().sock_flushnext()unlocks the socket, but TCP does not send any data until the next write function is called.4.2.2 Time-Out Settings
There are many time-out settings in TCP. These are necessary because the TCP socket needs to be able to take meaningful actions when things take longer than expected. For good performance, it is also sometimes necessary for the socket to delay slightly some action that it could otherwise perform immediately.
The time-out settings currently apply to all sockets; they cannot be applied selectively because they are in the form of macro constants.
In general, you can improve overall TCP performance by reducing some of the time-out settings, however there is a law of diminishing returns, and you can also start to reduce overall efficiency. What may be good settings for a local Ethernet connection may be very poor for an Internet connection. Note that if you optimize time-out settings for a particular network environment, you will need to document this so that your end-users do not inadvertently use your application in the wrong sort of environment. For this reason, it is best to use the default settings for general-purpose applications, since the defaults work well in worst-case settings without affecting best-case performance unduly.
TCP is internally adaptive to network bandwidth and RTT, which are the main variables. Some of the time-out settings only apply to an initial "guess" of the network characteristics; TCP will converge to the correct values in a short time. Specifying a good initial guess will help TCP in the initial stages of establishing a socket connection.
4.2.2.1 Time-Out Setting Constants
The following constants can be #defined before including
dcrtcp.lib. They specify various time intervals that have a bearing on connection performance.RETRAN_STRAT_TIME
This defaults to 10ms. It specifies the minimum time interval between testing for retransmissions of data for a particular TCP socket. This not only provides an upper bound for packet transmission rate, but also cuts down on CPU overhead. Since retransmissions are basically driven from
tcp_tick(), the less time used intcp_tick()processing the more time is left for your application. Note that the actual minimum retransmit interval is defined byTCP_MINRTO; this setting only affects the testing interval.Retransmissions are only required when there is an unexpected surge in network congestion, which causes packets to be delayed well beyond the average or even dropped.
It is not recommended to reduce this setting, but you could increase it to about 100ms to cut down on
tcp_tick()overhead without materially affecting most applications.TCP_MINRTO
Defaults to 250ms. This specifies the actual minimum time between TCP retransmissions. Reducing this will not affect performance in a properly functioning network, and may in fact worsen efficiency. Only in a network that is dropping a high percentage of packets will this setting have any real effect. On local Ethernet connections, genuine packet drops will be practically non-existent. The most likely cause of delays is if a host CPU is tied up and unable to perform network processing. On Internet connections, setting a retransmit time shorter than 250ms is just as likely to worsen the congestion which is causing packets to be dropped in the first place.
The only case where this value might be profitably reduced is the case of a point-to-point link where there is a lot of packet loss (maybe because the RS232 wiring is routed near an industrial welder). In this case, any packet loss may be assumed to be because of noise or interference, not because of router congestion. In the Internet, most packet loss is because of router congestion, in which case there is nothing to be gained by reducing
TCP_MINRTO.Another reason for not reducing this setting is that modern TCP/IP implementations only acknowledge every 2nd packet received (or after a short time-out - see
TCP_LAZYUPD). Normally, this will happen within the 250ms time interval, so there will be no unnecessary retransmission.TCP_TWTIMEOUT
This defaults to 2000ms (2 seconds). This is one area where embedded system requirements conflict somewhat with recommendations in the standards documents. The "time-wait" time-out is a waiting period that is necessary when a socket is closed. This waiting period is supposed to be twice the maximum lifetime of any packet in the network. The maximum packet lifetime is 255 seconds, so the time-wait time-out should be about 8 minutes. The purpose of the waiting time is to allow both ends of the connection to be satisfied that their respective peer has agreed to the close and acknowledged it.
This wait time only affects the closed socket i.e., the unique socket combination of IP addresses and port numbers. It means that when a socket is closed, the same socket cannot be re-opened until at least 8 minutes have passed.
This is usually no problem for systems that have large memories to hold the state of recently closed sockets. For an embedded system, which has a limited pool of sockets and limited memory for storing connection states, this wait time is inconvenient since the socket structure cannot be re-used until the time-wait period has expired.
The default time-wait period is thus set to 2 seconds in the Dynamic C TCP/IP libraries. This will work perfectly well for local Ethernet connections, where the maximum packet lifetime is of the order of milliseconds. For Internet connections, this may be a bit short, but will generally be satisfactory.
If in fact the time-wait period is too short, the worst that will happen is that one of the peers will be unsure about whether the other end got the last segment of data, and confusion may happen if old packets (from this connection) happen to arrive after the close. This latter case is unlikely to happen, but if it does then it will eventually be resolved when the socket connection process times out.
If you want your application to be more robust, you can increase this value. 8 minutes is an extremely conservative value. Most implementations shorten this to 2 minutes or 30 seconds, since packets are extremely unlikely to survive more than 15 seconds.
Note that this value is only used if you do not specify the
tcp_reserveport()option for the local port of a passively opened connection. If you specify reserveport, then the time-wait period is set to zero.TCP_LAZYUPD
This defaults to 5ms, and is used for several purposes. The first use is to reschedule transmission attempts that could not be processed owing to local resource shortages. For example, if a previous packet is still being transmitted via a slow PPP interface, the current packet may need to be delayed. Similarly, the Ethernet hardware can be busy. In these cases, the TCP stack needs to try again a short time later.
The second use is to allow time for further information to come in from the network before transmitting otherwise empty packets. TCP has two main reasons for transmitting packets with no data content. The first is acknowledgement of incoming data when we have nothing to send, and the other is to update our receive window to the peer. The receive window tells the peer how much data it can transmit which we can store in our socket receive buffer. This window needs to be updated not only when we receive data, but also when the application reads data out of the receive buffer.
Rather than send these empty packets as soon as possible, it is often profitable to wait a short time. In the case of window updates, this can allow the application to write some data after the read which updated the window. The data can be sent with the window update, which improves efficiency because one packet can do the work of two. For receive data acknowledgements, the same trick can be applied i.e., piggy-backing on some additional data.
These optimizations can be taken advantage of quite often with most applications, so it is worth while specifying the lazy update time-out to be at least a few ms. Lowering the lazy update interval can slightly improve latency and throughput on high-speed (i.e., local Ethernet) connections.
4.2.3 Reserved Ports
As mentioned in the
TCP_TWTIMEOUTdescription, you can specify that certain TCP port numbers have the special property of being "reserved." If a port is reserved, it has two effects:
A number of pending connections can be queued while a socket connection is established. The pending connections form a FIFO queue, with the longest-outstanding pending connection becoming active after the current connection is closed.
The time-wait time-out is truncated when the current connection is closed.
Together, these increase the performance of passively-opened sockets, which are designed to implement server functions such as FTP and HTTP servers. Reserving a port has no effect on actively opened sockets (i.e., "clients"), and does not affect its performance during the life of each connection.
The functions
tcp_reserveport()andtcp_clearreserve()respectively enable and disable a TCP port number from being treated in this manner.4.2.4 Type of Service (TOS)
Type Of Service is an IP (Internet Protocol) header field that causes routers in the Internet to handle packets according to the specified service level. TOS has not been widely deployed in the past, but recently Internet routers have been able to take advantage of the TOS field.
TOS generally takes one (and only one) of a pre-specified number of values. The currently available values are:
IPTOS_DEFAULT- the default, used when none of the following are obviously applicable.
IPTOS_CHEAP- minimize monetary cost. Used for bulk transfers where speed or reliability are not of concern, and you are paying by the packet.IP does not guarantee that the TOS setting will improve the objective performance, however, it at least guarantees that performance will not be any worse than if the default TOS was selected. In other words, it doesn't hurt to specify TOS, and it may even help!
TOS can be set on a packet-by-packet basis; however, the TCP stack only allows a TOS to be set for a socket (TCP or UDP) which is used for all packets until changed. The function
sock_set_tos()is used to set the TOS field.4.2.5 ARP Cache Considerations
ARP (Address Resolution Protocol) is only relevant for non-PPPoE Ethernet, not PPP interfaces. Although it works in the background, mainly to translate IP addresses into Ethernet MAC addresses, there are some considerations which apply to TCP (and UDP) performance.
There is a limited size cache of address mapping entries, known as the ARP Table. The cache is necessary in order to avoid network traffic each time a socket connection is established. It must be sized appropriately to avoid "cache misses" as much as possible.
If the controller board is to be used exclusively in "server mode," i.e., TCP sockets opened passively, then the cache does not have to be very big. If, on the other hand, the controller is going to actively establish sessions with a number of hosts, then the cache should be big enough to contain an entry for each host such that entries do not get pushed out for at least a few minutes.
The ARP Table also contains special entries for routers that are on the local Ethernet. These entries are important, since they represent entries for all hosts that are not on the local LAN segment subnet.
The default sizing rule for the ARP Table allocates an entry for each interface (including point-to-point) plus 5 entries for each Ethernet interface in use. The single entry for each interface is basically reserved for routers, on the assumption that each interface will probably require a router to allow connections to hosts which are farther afield. The additional 5 entries (for Ethernet) are for non-router hosts that the controller board will need to talk to.
This implies that 5 connections to hosts on the Ethernet subnet can be supported simultaneously, without any of the entries being pushed out. If the table is full, connection to a 6th host can be made, with the least-recently-used host entry being pushed out to make room.
If your application connects with, say, ten hosts in random order, it is likely that the ARP Table will need to be increased in size. If in doubt, increase the table size, since each entry only takes up about 32 bytes.
4.3 Writing a Fast UDP Request/Response Server
UDP is a lightweight protocol wrapper that adds port number "multiplexing" and checksums to basic IP packets. Being lightweight, it is capable of being very fast, with low CPU overhead. UDP is often selected for custom application protocols that do not need the reliable, stream-oriented, connections of TCP.
UDP is connectionless, however, application designers can think in terms of client-server or transaction-based programming. A popular design for UDP servers is to have the controller board listen for incoming datagrams. Each incoming message is processed and an immediate reply is sent. It is left up to the client to retransmit messages if it did not receive a reply in the expected time frame. The server, however, is extremely simple to implement, which allows it to serve more clients than a TCP-based server could manage.
Starting with Dynamic C 7.30, a data handler facility has been added to UDP (as well as TCP) sockets. The data handler is especially efficient for UDP, since it allows the datagram to be processed without any copying to the socket buffer.
The UDP data handler is a callback function whose address is supplied on the
udp_extopen()call. For simple request/response applications, the only application requirements are to define the data handler, and calltcp_tick()repeatedly in a loop after setting up the TCP/IP stack and opening the UDP socket.The sample program
Samples\tcpip\udp\udp_echo_dh.cshows how to implement a simple UDP echo server using the technique described in this section.4.4 Tips and Tricks for TCP Applications
This section contains miscellaneous suggestions for getting the most out of your TCP-based applications.
Application design requirements that affect TCP performance include:
- the responsiveness and throughput requirements of the application
- how often
tcp_tick()can be called- whether socket is used in ASCII or binary mode
- whether multitasking or "big loop" programming style.
The list of application types at the beginning of this chapter is used as a basis for discussion. Your application may neatly fit into one of these categories, or it may be a combination of several. In either case, you should try to follow the programming guidelines unless you are fairly experienced with the Dynamic C TCP/IP libraries.
4.4.1 Bulk Loader Applications
This type of application is idle (from the TCP/IP point of view) most of the time, but this is punctuated by periods of intensive data transfer. Applications which exhibit this characteristic include data loggers and file transfer agents e.g. FTP server or client. Sending email via SMTP also comes under this category.
The main application requirement is good utilization of the available bandwidth i.e., highest throughput. This is achieved by using the largest practical buffer sizes, processing data in the largest possible chunks, and minimizing data copying. Since the Rabbit processor is CPU-bound when dealing with high speed transfers (over Ethernet), every time the data is "handled" it reduces the ultimate throughput.
The Nagle algorithm should be left ON. Time-outs should be set to generously high values to avoid unnecessary retransmissions. The TOS should be set to IPTOS_CAPACIOUS.
Bulk TCP transfers are most efficient when the packet size is the largest possible. The largest packet size is limited to the MTU size of the network connection. You can assume that 600 bytes is a reasonable MTU for Internet connections. You can use up to 1500 for all supported interface types (except PPPoE, which is limited to 1492), however it is best to use 600 if Internet connections are expected. If the Internet MTU is in fact less than the expected value, then packets may become fragmented, which lowers efficiency. You cannot do much about this except reduce the MTU.
When the MTU is determined, the maximum TCP packet data length will usually be the MTU minus 40. The 40 bytes are for the IP and TCP header overhead. For a 600 byte MTU, the maximum TCP data segment size will be 560. Thus, TCP performance will be best if data is handled in multiples of 560 bytes.
It is not quite this simple, however. When a TCP connection is opened, both sides can agree to use different data segment sizes than the default. Generally, whichever side has the smallest MTU will place a limit on the segment size. This is negotiated via the TCP MSS (Maximum Segment Size) option.
In your program, rather than hard-coding the optimum chunk size, you can define a symbol as follows:
#define TCP_CHUNK_SIZE (MAX_MTU - 40)where
MAX_MTUis a symbol defined by the library to be the actual MTU in effect. For multiple interfaces, it is probably better to use the minimum value of any interface. You can find out the current MTU for an interface usingifconfig(iface, IFG_MTU, &mtu, IFS_END)which will read the MTU for interface "iface" into the integer variable "mtu".Most of the time, the TCP socket MSS will be equal to the fixed value above. In cases where it is smaller, there will not be a noticeable decrease in efficiency.
Once you have determined the appropriate chunk size, use
sock_awrite()orsock_axwrite()(for extended memory data) with the specified chunk size, except possibly for the last chunk.sock_awrite()and friends are available starting with Dynamic C 7.30. They have the advantage that the data is completely buffered, or not at all.sock_fastwrite()may buffer less than the requested amount, which means that your application needs to keep track of the current position in the data being sent.sock_awrite()does not do things "by halves," so it is easier to keep track in the application. Because it will not do small data moves, it is also slightly more efficient in terms of CPU time.4.4.2 Casual Server Applications
A casual server is a term we use for applications that need to respond to occasional requests for information, or commands, without large data transfers. Although the amount of data transfer is limited, the application still needs to be as responsive as possible. Example applications of this type include machine, building and power controllers. Interactive servers are also included, such as telnet.
The main goal here is to achieve low latency.
4.4.3 Master Controller Applications
Master controllers are responsible for coordinating access to a number of other devices (via TCP/IP or other types of communication) or acting as an "access concentrator". Data transfer may be low to moderate. Latency should be minimized.
4.4.4 Web Server Applications
The TCP/IP libraries include web server software.
HTTP.LIBtakes advantage of the TCP library to get good performance. Your application can still affect web server performance, since it may be responsible for generating content via CGI callback functions. Web servers have much the same characteristics as "bulk loaders," however, they are such a common case that they deserve special treatment.4.4.5 Protocol Translator Applications
A protocol translator basically converts between a TCP data stream and some other type of data stream, for example asynchronous serial data. The data may flow in either or both directions.
This type of application has the most stringent requirements on both throughput and latency. This is because the incoming stream may not be amenable to any sort of flow control: it is necessary for TCP to keep up with a possibly high data rate. Also, the more timely the transmission of data, the more useful the protocol translator.
1 Assuming there is no other traffic on the Ethernet, and that collisions are rare. This is rarely the case, so a 50-80% utilization of bandwidth is considered the maximum desirable Ethernet load.
| TCP/IP Manual Vol 1 |
<<Previous | Index | Next>> | rabbit.com |