KERMIT PROTOCOL STREAMING ON RELIABLE CONNECTIONS D R A F T # 7 Wed Dec 16 15:06:28 1998 Updated Fri Dec 24 16:50:25 1999 (chars that must be prefixed) (First Draft: November 1997) THE PROBLEM Kermit file transfer protocol has often been compared unfavorably with streaming protocols such as FTP, Zmodem (when configured to stream), and Ymodem-G. Unlike Kermit, these protocols are designed to take full advantage of a reliable connection, so they can take liberties and therefore tend to go faster. (Yes, that's the problem :-) In recent years, Kermit protocol has proven itself as fast as, yet more robust than, other protocols on most serial communications connections. Yet on TCP/IP connections, Kermit is often dramatically slower thant FTP, which can be attributed to underlying heuristics in the TCP/IP stack such as the Nagle and Delayed ACK algorithms. First, some definitions: Transport: The underlying connection on which the Kermit program writes and reads Kermit packets. Primary Channel: The portion of the connection used for sending packets from the file sender to the file receiver. Reverse Channel: The portion of the connection used for sending packets from the file receiver to the file sender. Unlike FTP, Ymodem-G, and (non-windowed) Zmodem, Kermit is a sliding-window protocol with selective retransmission, meaning every packet must be ACK'd, and selected packets can be retansmitted to fill in holes (in contrast to a go-back-to-n protocol in which any error rewinds the transfer to the point of error and starts over from there). Thus, Kermit can become blocked waiting for application-level acknowledgements to arrive on the reverse channel. Even when a window and packet size is used that is large enough to keep the primary channel fully occupied, the underlying transport might delay transmission of ACKs on the reverse channel because they are short, or because the reverse channel is congested, or for any other conceivable reason. Kermit protocol is designed for unreliable transports where packets can be lost, damaged, duplicated, echoed, or delivered out of order. Thus ACKs are required for every packet. A SOLUTION But what if we have a reliable transport, such as the one that FTP always has? Reliable Transport: A transport that delivers a data stream without loss or corruption and with all bytes in the same order in which they were sent. If it can't do that, it delivers a fatal i/o error. Therefore, on a reliable transport, packets are never damaged, lost, duplicated, or delivered out of order as long as the connection remains open. Therefore, per-packet ACKs are not required, NAKs will never be sent, and retransmission is never necessary. On such a connection, Kermit can be modified to not send or expect ACKs during the data phase of a file transfer. This is called streaming; it is equivalent to using an infinite window size. The object of streaming is to eliminate any ACK-related bottlenecks that would needlessly impede Kermit's performance on reliable connections, allowing it to perform comparably to other protocols that are specifically designed for reliable connections, but in a way that does not depend on specific knowledge about the underlying platform or transport. Streaming is intended primarily for use on TCP/IP client/server connections, which will become more common once we have TCP-based Kermit servers similar to FTP servers, but can also be used in other settings. HOW DO WE KNOW WHEN WE HAVE A RELIABLE TRANSPORT? The Kermit program that makes the connection usually knows what the underlying transport is, and therefore whether it is reliable. When it is a TCP connection, in most cases it can be considered reliable, since error detection, error correction, pacing, and sequencing are done by TCP, IP, and the layers below. Similarly for X.25 and other reliable end-to-end protocols. A serial connection, on the other hand, should not be considered reliable, even when error-correcting modems are involved, for all the well-known reasons (lack of effective flow control, interrupt conflicts, loose wires, etc). The remote Kermit can not usually tell what kind of connection it has, and so some means is required to tell it that it has a reliable one. This can be done by command, or the information can be conveyed from the local Kermit via protocol. In some cases, a reliable transport is not truly reliable. Examples: . A Telnet connection might not be 8-bit clean. . A TCP connection might be to a terminal server that makes a dialout call. . A Telnet or Rlogin connection might be through an intermediate Telnet or Rlogin client, which filters out the 8th bit or has an escape character. . Telnet to VMS can lose characters if the remote session has certain parameters set, such as TERMINAL /NOTTSYNC and/or /NOHOSTSYNC. Note: some of these are transparency problems, which are independent of whether the transport is reliable. COMMANDS Commands are necessary to let the user have the final say about whether a connection is reliable: SET RELIABLE { AUTOMATIC, ON, OFF } And on the C-Kermit / K95 command line: kermit -I (uppercase I, like Internet) specifies a reliable connection (used in remote mode). SET RELIABLE ON (and -I) can have all sorts of effects, and so in themselves do not control the streaming feature. If not given, then the Kermit program's internal "reliable" variable is set automatically according to the connection type. Use this command to override Kermit's decision. SET RELIABLE AUTO should be the default. It allows the local Kermit to automatically SET RELIABLE ON or OFF according to the kind of connection it has made (normally, TCP and X.25 connections are reliable, others are not). It lets the remote Kermit learn whether the connection is reliable from the local one. Streaming is controlled by a separate command: SET STREAMING { ON, OFF, AUTO } AUTO should be the default setting for Kermit programs that support streaming. It means that if the local Kermit program has SET RELIABLE ON, or if is has SET RELIABLE AUTO and believes it has a reliable connection, then it offers to stream. With SET STREAMING AUTO and SET RELIABLE AUTO (or ON), the remote Kermit always offers to stream. ON means that the Kermit program offers to stream no matter what kind of connection it thinks it has. OFF means that the Kermit program refuses to stream. Thus, in cases where both Kermit programs *know* they have a reliable connection, or when one Kermit knows and tells the other, streaming occurs automatically, in all others, it does not occur unless the user takes special action to enable it. For example, if Kermit on A telnets to B and starts Kermit there, and both RELIABLE and STREAMING have their default settings of AUTO, then Kermit A tells Kermit B the connection is reliable, and so they agree to stream. If Kermit A telnets directly to a TCP socket on which Kermit B is listening for incoming connections, then both know they have a reliable connection, and streaming occurs automatically. Both these scenarios can fail, of course, in the hopefully rare situation in which the caller has a TCP connection to a dialout terminal server, which is used to call another terminal server, from which a TCP connection is made directly to a Kermit socket. The command, SHOW STREAMING, displays the current settings of the STREAMING and RELIABLE variables, and explains under what conditions streaming will be done, and whether it was done in the most recent file transfer, if any. NEGOTIATION When STREAMING is ON, or when STREAMING is AUTO and the Kermit program believes it has a reliable connection, it offers to stream by setting Bit 3 (reserved until now) in the WHATAMI byte of the Initialization String. IMPORTANT: The WHATAMI spec did not define this bit, and it specified that the FLAG3 bit was to be set when Bit 3 was defined. This requirement has been dropped; see next section. If both Kermit programs set Bit 3, they will stream; if not, they will not stream. Such agreement is not sticky; it does not persist beyond the transaction in which it was negotiated. For best results, if possible, although it violates all principles of layered networking protocols, each Kermit program should ensure that the maximum packet length it allows the other to send is optimized for the underlying transport. For example, if the TCP Maximum Segment Size is 1450, then 1450 (or slightly less), or any multiple thereof up to 8700 (or the TCP SENDBUF size, whichever is less), would be a good choice, forcing Kermit packets to fit nicely withing TCP packets, whereas 1451 would be a terrible choice, causing a full-size TCP packet to be sent, and then a "runt" constructed that is likely to languish in an output buffer for some time due to TCP congestion avoidance heuristics. CLEARCHANNEL PROTOCOL (Unrelated to streaming, but documented here anyway.) The WHATAMI spec has never been published. Therefore it is safe to change the definition of the FLAG3 bit in the WHATAMI byte. Consider: . If Bit 3 is 0, there will be no streaming. . If Bit 3 is 1, there will be no streaming unless the other Kermit knows about streaming and sets this bit also. If it doesn't know about streaming, it won't set this bit. Since no streaming versions of Kermit have yet been released to the public, not even as alpha tests, there is no need for the FLAG3 bit and we can redefine it as follows: Bit 4: WMI_CLEAR Each Kermit program sets this bit if it KNOWS it has an 8-bit connection that transparent to all 256 bit patterns, or a 7-bit connection transparent to all 128 bit patterns, EXCEPT allowing for the possibility that Telnet NVT rules might or might not apply. The clear-channel property is independent of the 8-bit cleanliness (parity) and the reliability of the channel. Thus, it is possible to have a clear channel on a 7-bit connection, or over an unreliable transport; the only criterion is that the channel be transparent to all 7-bit or 8-bit bytes, with the exceptions noted below. A clear channel can be clearly identified when the program has opened a TCP socket, since most other communication paths are through devices that have escape characters or sequences (such as terminal servers or modems), or through an intermediate Telnet, Rlogin, or other connection program, etc. Since remote-mode Kermit programs usually have no clue about the connection method, they normally will not believe they have a clear channel. When a Kermit program receives a parameter string in which the clear-channel bit is set, this is permission to send any or all control characters without prefixing, except on Telnet connections, where the following must be prefixed: 1. CR (decimal 13) because of NVT rules, and: 2. DEL (decimal 127) and IAC (decimal 255), and: 3. XOFF and XON (decimal 17 and 19), often used for flow control, and: 3. (optionally, but recommended for safety) the Kermit packet start and end characters. These exceptions allow for the possibility that the connection goes through a Telnet server without knowing it. If the Kermit program knows it has a connection that does not use Telnet NVT rules (such as, e.g., an Rlogin connection), it can omit (1) and (2). Any Kermit program that sets the clear-channel bit must be capable of receiving ANY bit pattern within a packet, including NUL (0), CR (13), and IAC (255). In the event of a misjudgment about the transparency of the channel, of course the transfer is likely to fail, but that has always been the case. The user can override the automatic clear-channel determination with SET CLEARCHANNEL { ON, OFF, AUTO }. The WHATAMI spec is hereby amended to redefine Bit 4; its old FLAG3 value is retired and it is now the CLEARCHANNEL indicator. STREAMING PROTOCOL Once the two Kermit partners have agreed to use streaming protocol, the transfer takes place in the normal manner, except: . Streaming is activated in the file receiver after the first F or X packet is received, i.e. after it knows that streaming is negotiated and that any retransmissions of the S/Y exchange have already occurred and so will not be fatal. From this point streaming remains in effect until the end of the transaction, i.e. after the B/Y exchange or an E packet. . The sender does not wait for ACKs to D packets, but keeps sending the file without pause until the end (unless interrupted), at which point it sends a Z packet and waits for its ACK in the normal manner. . During the data phase, the file sender must sample the reverse channel in case Error or cancellation packets arrive. This can be done using a nondestructive communications input-buffer peeking technique, and should not affect performance . The receiver does not send ACKs for D packets, but simply decodes incoming data and disposes of it in the normal manner (e.g. writes it to disk), except when the user interrupts the transfer. . The receiver does not time out during streaming. Once streaming is negotiated, the timer it turned off until the end of the transaction. . The receiver does not send NAKs, since there is no longer any window management -- the sender might be many window cycles ahead of the receiver by the time a NAK arrives. In any case, by the definition of "reliable transport", there is no need for NAKs. The underlying transport handles timeouts, pacing, and flow control automatically. When the Z packet arrives, the file is closed and the Z packet is acknowledged. . If a damaged or out-of-sequence data packet arrives at the receiver during streaming, this is fatal. The receiver of such a packet must respond with an Error packet and the transfer must cease. Similarly, if a NAK packet arrives at the sender during streaming, this too is fatal. . The Kermit partner that is in local mode must still sample the keyboard for interruptions (cancel file, cancel batch, send Error packet & quit). The "retransmit previous packet" interruption, however, should be ignored. . If a file (X) or group (Z) interruption is signaled from the keyboard to the file receiver, only one ACK(X) or ACK(Z) should be sent. . The heuristic of clearing the communications input buffer when the window size is 1 and the desired packet has just been received must not be used when streaming. It is essential that both sides either (a) engage in streaming protocol, or else (b) not engage in it. No mixing and matching. If the sender waits for ACKs that never come, the transfer will hang as soon as the first window fills. If the sender gets ACKs or NAKs, it won't know which packet they are for and will not be able to handle them. Additional notes: . Streaming is independent of other negotiated parameters like packet length, and window size, 8th-bit prefixing, locking shifts, etc, and can be used in either text- or binary-mode transfers. It is also independent of unilateral (non-negotiated) settings like control-character prefixing. . On TCP connections, it is helpful at the low level to issue read requests for at least 1/2 the TCP Receive Window size; in many TCP/IP implementations, this can have the effect of opening the TCP Receive Window and therefore minimize blockage at the TCP level. STREAMING ON HALF-DUPLEX CONNECTIONS Sliding windows requires a full-duplex connection to allow the file sender to sample the reverse channel. But a half-duplex connection, such as we normally have to IBM mainframes, does not have a reverse channel; conceptually there is only one channel that switches direction back and forth. In this case, once the sender begins streaming, the receiver will not be able to signal an interruption, and thus the transfer must proceed to completion. If we are willing to accept this restriction, we can implement streaming in IBM Mainframe Kermit. When a line-turnaround handshake character is used, as on an IBM mainframe linemode connection, the non-mainframe file sender should append it to each packet that requires an ACK (I, S, F, A, Z, B), but not to Data packets. STREAMING ON NOT-REALLY-RELIABLE CONNECTIONS Certain connections might be reliable in all respects except transparency. For example, you might have Telnet connection that strips the 8th bit, or that is sensitive to certain control characters. Streaming can still be used on such connections in conjunction with the appropriate Kermit adjustments, such as SET PARITY SPACE, SET CONTROL PREFIX , etc. Certain dialup connections using error-correcting modems and hardware flow control, in which the connection between each modem and its computer is also error-free by virtue of a lack of interrupt conflicts, noise, interference, loose connectors, buffer overruns, etc, might lend themselves streaming. Kermit allows you to try it if you want, at your own risk; just tell each Kermit partner to SET RELIABLE ON, and then make sure to also set up hardware flow control. If a block check or sequencing error is detected during streaming, it is fatal; the message is "Transmission error detected on reliable link". Kermit can detect errors and fail more promptly (and gracefully) than most other streaming protocols. PRELIMINARY RESULTS All trials are conducted transferring real files over real network and serial connections (not internal "localhost" connections), disk-to-disk (no RAM disks, etc). The conditions are real, not controlled; the hosts are shared, not dedicated, and when a network connection is involved, it too is a shared, production network. Thus the numbers are not precise and repeatable. However, large numbers of samples over long periods of time tend to smooth over the effects of localized host or network effects. TRIAL 0: TCP/IP, Local Ethernet The first trial is only to give a feel for the effect of streaming over the widest possible range of Kermit packet and window sizes, rather than making assumptions. Transferring a 4MB Sparc executable (the SunOS version of C-Kermit 6.1, concatenated with itself 4 times) from a Sparc-20 to an UltraSparc-xxx over 10BaseT (10Mbps), under moderate network and host load, using C-Kermit 6.1 Alpha.10 on each end. The two Kermit programs are connected via TCP directly socket-to-socket, rather than through a Telnet server. Round-trip-time for ICMP echo is 2msec. Kermit packet sizes of 480 to 8640 in increments of 480 (18 different sizes) were used in conjunction with window sizes 1-31 to transfer the file, once with streaming off, again with it on, for a total of 1116 samples. For each sample, the speed in characters per second (CPS), plus the packet length, window size, and streaming status were recorded in a table, and the table was analyzed by SAS. Univariate analysis of CPS figures showed: Streaming Nonstreaming Max CPS 699050 (11) 699050 (2) Min CPS 99864 (1) 47127 (1) Mean CPS 441275 380094 Median CPS 455033 381300 Std Dev 123663 135782 By way of comparison, FTP transfer of the same file between the same two computers on the same network under the same conditions proceeded at between 150 and 180Kcps in 20 trials (before and after the Kermit trials). Correlations of throughput with window size, packet length, and the product of packet length and window size (i.e. total packet buffer size) were: Streaming Nonstreaming Window Size (W): -0.05 0.24 Packet Length (P): 0.34 0.51 W x P: 0.18 0.46 The insignificant figure for window size in the streaming case is not surprising, since streaming effectively ignores the window size setting. The correlation between CPS and Streaming (0 or 1) was 0.23, a positive number indicating that there is a significant, if not strong, relationship between streaming and throughput; when streaming is used, throughput tends to be higher than when streaming is not used. Out of 558 trials, streaming beat nonstreaming 346 times and equaled it 74 times. Nonstreaming beat streaming 138 times. Thus streaming was as good as or better than streaming in 75.3% of the cases. An identical run performed late at night when the network and hosts were minimally loaded gave similar results, except with less variability due to load spikes: Streaming Nonstreaming Std Dev 99265 147947 This shows that thoughput tends to be more consistent with streaming. Correlations in the late-night run were stronger too: Streaming Nonstreaming Window Size (W): 0.02 0.39 Packet Length (P): 0.55 0.54 W x P: 0.36 0.60 This run showed a 0.30 correlation between streaming and throughput. A glance at the raw data shows that the maximum throughput (699Kcps) can occur for almost any window size, including 1, but occurs most frequently when the window size is between 10 and 19: 1-9: 6 10-19: 14 (The median window size for fastest transfers is 14) 20-31: 5 Maximum throughput never occurs unless the packet length is 4K or greater: 0-3K: 0 4-5K: 3 5-6K: 5 6-7K: 2 7-8K: 6 8-9K: 7 TRIAL 1. TCP/IP, Local Ethernet In this trial we transfer an 8MB file over the same connection as in Trial 0 and vary the window size from 10-20 and the packet length from 4350 to 8700 by steps of 1450. The idea is to rule out the cases where streaming wins automatically simply because it is equivalent to an infinite window size. Streaming Nonstreaming Max CPS 682666 682666 Min CPS 341333 256000 Mean CPS 595009 563725 Median CPS 630153 630153 Std Dev 81941 109767 Streaming Nonstreaming Window Size (W): 0.00 0.05 Packet Length (P): 0.25 0.27 W x P: 0.17 0.12 Correlation of CPS to Streaming (0 or 1): 0.16 Of the 44 pairs of transfers, streaming beat nonstreaming in 22, equaled it in 9, and lost in 13. Thus it was better or equal to nonstreaming in 70.5% of the cases, but not by a huge amount. TRIAL 2. Long-Distance TCP/IP, Moderate Latency Same Sparc-20 host in NYC via Internet to Netlab1, a PC running Unixware 2.1.1, at Utah State University, socket-to-socket. On this connection there is an average round-trip time of 69msec, and the available bandwidth is lower too. Here we use a 1MB Sparc executable (the SunOS C-Kermit 6.1 executable) as the test file rather than the 4MB file, since 1MB takes enough seconds to transfer over this link to give good variation in throughput numbers. Streaming Nonstreaming FTP Max CPS 262144 (25) 262144 (15) 130000 (1) Min CPS 52428 (1) 6026 (1) 50000 (1) Mean CPS 164585 124784 74200 Median CPS 149796 123790 56000 Std Dev 56181 70618 29200 The FTP column is shown for comparison; 20 transfers of the same file in the same direction between the same two hosts were performed shortly before, during, and shortly after the Kermit transfers. Correlations: Streaming Nonstreaming Window Size (W): 0.34 0.57 Packet Length (P): -0.05 0.44 W x P: 0.16 0.69 CPS to Streaming: 0.30 TRIAL 3. Longer-Distance TCP/IP, Low Bandwidth, Greater Latency From SunOS in NYC to a DECstation 5000 (MIPS) running Ultrix 4.3 at the Japan National Laboratory for High Energy Physics, about 18 hops and 13,000 miles away. IP packet round-trip time is about 240 msec. FTP consistently transferred files of various sizes at 3600 CPS. In these trials, a 100,000-byte binary file was used (the first 100000 bytes of the Sparc C-Kermit executable). Window sizes were in the 20-30 range, on the supposition that it's a long pipe and needs more to fill it. Packet lengths are varied from 4350 to 8700. Streaming Nonstreaming Max CPS 5000 5882 Min CPS 425 (1) 436 Mean CPS 2180 2978 Median CPS 1963 2941 Std Dev 1061 1198 Correlations: Streaming Nonstreaming Window Size (W): -0.28 -0.20 Packet Length (P): -0.09 -0.24 W x P: -0.13 -0.29 CPS to Streaming: -0.34 Now this is a curious result! Increasing any of our performance options -- window size, packet length, streaming -- tends to reduce performance. No doubt there is an explanation, perhaps having to do with the extreme jerkiness of the connection. But in any case, both streaming and nonstreaming Kermit transfers can outdo FTP on this connection, and streaming transfers do work as advertised; even though the connection is slow and has long delays, it is reliable. Furthermore, the difference between streaming and nonstreaming is not large in absolute terms. TRIAL 4. Simulated IBM Mainframe Connection Here we are limited to 1 window slot, and the maximum packet length is 1920. We vary the packet length from 192 to 1920 in increments of 192, keeping the window size at 1, and transfer the 8M file with and without streaming. The host is not actually an IBM mainframe, since streaming code has not been written for it, but rather a Solaris system with C-Kermit 6.1 using IBM Mainframe-like settings. Streaming Nonstreaming Max CPS 524288 (2) 147168 (1) Min CPS 335544 (1) 13378 (1) Mean CPS 466280 84969 Median CPS 493447 144637 Std Dev 58844 54826 Correlation of CPS to Packet Length, Streaming: 0.83 Correlation of CPS to Packet Length, Nonstreaming: -0.43 (???) Correlation of CPS to Streaming (0 or 1): 0.96 The effect of streaming in this case is dramatic. (Granted, an IBM Mainframe Kermit program written specifically for TCP socket-to-socket connections would not have these limitations, but there's not much chance of that happening; however, the streaming modifications would be fairly simple to add to the existing mainframe version.) TRIAL 5. TCP/IP, Local Network, Microsoft Winsock IBM P90 Win95 to IBM PowerServer 850 with AIX 4.1. FTP goes at about 700Kcps. First I tested today's K95 build by downloading an 8M file from watsun to the PC on the local Ethernet: . No streaming: 818Kcps . Streaming: 819Kcps . Streaming/nodisk: 909Kcps (I know, it's cheating not to write to disk) Consistently faster than ftp, and probably the fastest Kermit times for nontrivial files (i.e. at least 4 times bigger than the channel capacity in cps) ever seen. And this was through the SunOS Telnet server, too. But I could never reproduce these results again -- after that, the best transfers I could get were in the 340Kcps range, even after rebooting, no matter which host I used on the other end. The mysteries of Windows, always the problem child, fooey... Anyway, benchmarking from Windows 95 to AIX, window sizes 10 to 30, packet lengths 1450 to 9000, transferring the 8MB binary file from Windows to AIX over the local Ethernet. It ran fine until trying to send an 86K TCP buffer (10 8600-byte Kermit packets), at which point it slowed to a crawl, like 45Kcps. This is not good. Manually changing the TCP SENDBUF to 200K gets around this problem (but why do I have to do that?). Results: Streaming Nonstreaming Max CPS 341333 303407 Min CPS 234057 141241 Mean CPS 306502 259081 Median CPS 321378 277774 Std Dev 33257 51867 Correlations: Streaming Nonstreaming Window Size (W): -0.05 0.14 Packet Length (P): 0.89 0.90 W x P: 0.85 0.90 CPS to Streaming: 0.50 (and in a later trial, this was 0.73). TRIAL 6. Serial Connection, V.32bis, 14400bps Preliminary serial trials were done using fixed large window and packet sizes. They compare uploading and downloading of two common types of files, with and without streaming. Configuration: HP-9000/715/33 -- 57600bps, RTS/CTS -- Telebit T3000 -- V.32bis+V.42 14400bps -- USR V.34+ Rackmount -- 57600bps, RTS/CTS -- Cisco TS -- Solaris 2.5.1. Packet size = 8000, Window Size = 30, Control Character Unprefixing Minimal (but including ^^, the Cisco escape character). This is not a truly reliable connection, and some trials failed when a bad packet was received (the failure was graceful and immediate, and the message was informative). The results of ten successful trials uploading and downloading two files with and without streaming are: Streaming Up Down on 3387 3246 txt (= C source code, 78K) 1576 1548 gz (= compressed gzip file, 85K) off 3246 3246 txt 1576 1548 gz Here we see little difference between streaming and nonstreaming. TRIAL 7. Serial Connection, V.34+, 31200bps Exactly like Trial 5, but dialing up with a USR Courier V.34+ rather than the Telebit T3000: Streaming Up Down on 5565 5565 txt (= C source code, 78K) 3406 3406 gz (= compressed gzip file, 85K) off 5194 5194 txt 3135 3041 gz Here we see fairly noticable improvements with streaming. CONCLUSIONS Further study needed. First of all, rule out the "straw man" cases, in which packet and/or window sizes are held lower than the connection will allow, since this automatically (and artificially) makes streaming look better -- sometimes ten, twenty, thirty, or forty times better. After casting out these unhelpful cases, it appears on the whole that streaming usually helps. But there are certain ones where it does not (such as the very slow connection to Japan), for reasons unknown. The Windows 95 version of Kermit will need to set its TCP SENDBUF and RECVBUF to about 200K or else streaming will knock it dead in its tracks. No other system exhibited this peculiarity. (I did try this on the UNIX end once or twice and found that it made little difference.) Although numerous lower-level tricks can be used to improve performance on specific platforms or connection methods, streaming occurs at a high, system-independent level of the Kermit protocol and therefore can apply to all types of platforms and (reliable) connections transparently. Meanwhile, further tuning is also needed. Even without streaming, the C-Kermit figures are pretty high due to recent internal tuning, and no doubt can be improved still more. APPENDIX I: Benchmark Script local \&s[] \%w \%p \%i \%m local \%a \%c \%o \%d \%x \%e \%n declare \&s[2] off on def \%n 7 declare \&p[\%n] 1450 2900 4350 5800 7250 8630 9010 ; Packet lengths def _file x ; Name of file to transfer def \%m 0 def \%c 0 def \%d 0 def \%e 0 set file display brief set control unprefix all set control prefix 0 1 255 set transfer bell off set file patterns off set file type binary remote set file collision overwrite if fail stop 1 {REMOTE SET FILE COLLISION FAILED: \&s[\%i] \%w \%p} if open write close write if exist bench.log rename bench.log bench.log.\v(ndate).\v(ntime) open write bench.log if fail stop 1 BENCH.LOG: can't open write file {; BEGIN: \v(date) \v(time). } ask \%a { Log comment: } writeln file \%a writeln file {; FILE=\fpathname(\m(_file)), SIZE=\fsize(\m(_file))} for \%w 10 32 2 { set window \%w for \%p 1 \%n 1 { for \%i 1 2 1 { set streaming \&s[\%i] remote set rec pack \&p[\%p] if fail stop 1 {REMOTE SET PACKET LENGTH FAILED: \&s[\%i] \%w \%p} echo S=\&s[\%i] W=\%w P=\&p[\%p] send \m(_file) if fail stop 1 {TRANSFER FAILED: \&s[\%i] \%w \&p[\%p]} incr \%c xif = \%i 1 { asg \%o \v(cps) } else { if > \v(cps) \%o incr \%d if = \v(cps) \%o incr \%e } .\%x ::= \%w * \&p[\%p] xif > \v(cps) \%m { echo NEW RECORD: \v(cps), asg \%m \v(cps) } writeln file \flpad(\v(cps),8) \frpad(\&s[\%i],3) \flpad(\%w,2) \flpad(\&p[\%p],4) \flpad(\%x,6) } } } writeln file {; FINISH: \v(date) \v(time) - transfers: \%c, max cps: \%m.} writeln file {; STREAMING win ratio: \feval(\%d+\%d)/\feval(\%c/2).} close write ; End