home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / mscwattc / readme.2nd < prev    next >
Encoding:
Text File  |  1992-01-04  |  14.7 KB  |  354 lines

  1. If you are programming with the Waterloo TCP library, the following notes
  2. may prove helpful and may have been ommitted from earlier copies of the
  3. programmers reference manual.
  4.  
  5. - - -
  6. Speed/Performance               (1/04/1992)
  7.  
  8.     The tcp code has undergone some mods to make it much faster, with
  9.     reads up to 120 kilobytes/s and writes up to 42 kilobytes/s on the
  10.     same subnet as my Sun.
  11.  
  12.     These speed were great, but my pc is usually on a subnet.  There, the
  13.     speeds were about 26 kB/s in writes and 70 kB/s in reads.
  14.  
  15.     For read's I was able to use good old sock_fastread.  For writes,
  16.     sock_fastwrite / sock_write just don't cut it because they are limited
  17.     to the small buffer size located in the tcp_Socket structure.
  18.  
  19.     I've added a new call which let's you get around that limitation,
  20.     sock_enqueue().  This new routine let's you specify a buffer of data
  21.     you wish to enqueue for transmission.  WATTCP records the address of
  22.     that buffer and its length, and starts to transmit it according to
  23.     the TCP rules.  You are not allowed to touch that buffer until all
  24.     the data is fully transmitted, something you can tell by using the
  25.     sock_tbused( s ) until it returns zero.  You must also keep calling
  26.     tcp_tick() or sock_tick() as those routines schedule transmissions.
  27.  
  28.  
  29.     Here is some sample code which writes out a disk file:
  30.  
  31.     tcp_open...
  32.     f->dhanle = open( ....
  33.     ...
  34.     while ( 1 ) {
  35.         /* check connection and do background stuff */
  36.         if (tcp_tick( s ) == 0) break;
  37.  
  38.         /* see if we can schedule more data */
  39.         if ( sock_tbused( s ) == 0 ){
  40.             printf("disk reading %u bytes\n", ftpdbufferlen );
  41.             if ((diff = read( f->dhandle, ftpdbuffer, ftpdbufferlen )) <= 0 ) {
  42.                 /* eof or possibly error condition */
  43.                 break;
  44.             } else {
  45.                 /* data ready to send */
  46.                 sock_enqueue( s, ftpdbuffer, diff );
  47.             }
  48.         }
  49.     }
  50.  
  51.     close( f->dhandle );
  52.     sock_close( s );
  53. - - -
  54. SMTPSERV  (in separate file: SMTPSERV.ZIP)
  55.  
  56.     This program accepts inbound mail and places it into mail spool files
  57.     almost identically to the way Phil Karn's NOS does.  You can download the
  58.     executable in pub/wattcp/smtpserv.zip.  If you find it useful or wish
  59.     to have it changed, let me know.
  60.  
  61. -----------------------------------------------------------------------------
  62.  
  63. Large Model                     (9/13/1991)
  64.     You can compile large or small model applications.  Check out the
  65.     MAKEFILE in the .\APPS subdirectory to see how easy it is to switch.
  66.  
  67.     The fullsrc.zip collection automatically produces large and small
  68.     model libraries.
  69.  
  70.     There is a bug with Borland C++ which can occasionally create
  71.     structures which cross stack boundaries and cause segment wraps.
  72.     The only condition which causes it is placing the tcp_Socket or
  73.     maybe udp_Sockets on the stack (automatic variables).  The same
  74.     program will work if recompiled in small model or if the structure
  75.     is placed on the heap or the data segment.  If your program
  76.     demonstrates the bug, tcp_open, udp_open, and tcp_listen
  77.     have code to warn you immediately and exit.  Hopefully the next
  78.     release of Borland C will solve this bug!
  79.  
  80. -----------------------------------------------------------------------------
  81.  
  82. TCP Fixes                       (9/13/1991)
  83.      The TCP portion of WATTCP has had numerous improvements.  I've managed
  84.      to significantly reduce the packet count while improving performance
  85.      and reliability.
  86.  
  87. -----------------------------------------------------------------------------
  88.  
  89. New Wattcp Programs
  90.      The latest release of MS-Kermit includes the WATTCP kernel, letting you
  91.      use it as a TELNET program.  I do not know where the ftp site is,
  92.      but it will probably be announced soon on Comp.protocols.tcp-ip.ibmpc
  93.      in the near future.
  94.  
  95.      LPD is a line printer server which will let a PC accept jobs from UNIX.
  96.      It offers some simple device restriction capabilities.  You can spool
  97.      jobs out any DOS file or device.  It requires a little few lines
  98.      of work to be used at any site other than mine.  It is available
  99.  
  100.      COMD.EXE is a simple program can be used to allow network access to
  101.      RS232 devices.  With a little work it could be converted into a modem
  102.      pool.  It is available from [129.97.128.196] pub/wattcp/comd.zip.
  103.  
  104.      If you have any improvements or new applications, please let me know.
  105.      I will gladly distribute them for you.
  106.  
  107. -----------------------------------------------------------------------------
  108.  
  109. Nested Config Files             (7/16/91)
  110.     Wattcp config files may be easily nested to allow for centralized
  111.     control of most parameters with local overrides, or user specific
  112.     extensions.
  113.  
  114.     To include a nested config file, use the following line in the
  115.     main config file:
  116.  
  117.         include = filename
  118.     eg. include = c:\local.cfg
  119.  
  120.     If the local file could not be found, a warning message is displayed.
  121.     You may wish to use a local file if it exists, but not display a message
  122.     if it does not.  To do that, simply prepend the filename with a question
  123.     mark.
  124.  
  125.     eg. include = ?c:\local.cfg
  126.  
  127.     When the nested file is complete it will return to the main file.
  128.  
  129.     The nesting limit is dependant upon the number of unused file handles
  130.     and the stack size.
  131.  
  132. -----------------------------------------------------------------------------
  133.  
  134. TCP/UDP Packet Dumps            (7/10/1991)
  135.     TCP/UDP packet dumping features have been added and may prove useful
  136.     for testing and debugging your applications.
  137.  
  138.     The debugger dumps packets, which gives you a feel for what the
  139.     kernal and the other end are trying to do.
  140.  
  141.     It's my job to try to make things go as fast as possible with as
  142.     few packets as possible (least load).  Actually, when you use the
  143.     dumping feature you usually INCREASE the packet count because the
  144.     dumper takes time which times out the scheduler and causes
  145.     retransmits.
  146.  
  147.     To include the debugging features in your program, add the line
  148.         dbuginit();
  149.     to your program *before* you call sock_init();
  150.  
  151.     To enable/disable the debugger, include the following lines in your
  152.     WATTCP.CFG file:
  153.         DEBUG.FILE=somename     # otherwise it will open a file called
  154.                                 # WATTCP.DBG in the current subdirectory
  155.                                 # somename could be con which will dump
  156.                                 # to the screen
  157.         DEBUG.MODE=DUMP         # to dump TCP/UDP data, looks a bit like
  158.                                 # DEBUG.COM
  159.    or   DEBUG.MODE=HEADERS      # to dump TCP/UDP headers
  160.    or   DEBUG.MODE=ALL          # to dump everything, headers and data
  161.  
  162.    You may write some textual data directly to the file.  Remember, you
  163.    must send a 'C' string ending with a 0, and you must include your
  164.    own CRLFs.
  165.  
  166.         db_write( char *msg );
  167.  
  168.    NOTE: If you use this feature and you also use usr_init, you
  169.          must chain usr_init as described in the programmers manual,
  170.          and as show in TCPINFO.C.
  171.  
  172. -----------------------------------------------------------------------------
  173. Good UDP Support                (6/5/1991)
  174.    Initially, only standard socket calls could be used for UDP.  That was kind
  175.    of shabby because UDP tends to be higher traffic, has no flow control, and
  176.    you wish to know record boundaries.
  177.  
  178.    The new code allows you to declare a big buffer into which the incomming
  179.    UDP packets will be bufferred.  Once initialized with sock_recv_init, the
  180.    buffer is used until the socket is closed.  NOTE: sock_recv... and the
  181.    regular socket input routines are MUTUALLY EXCLUSIVE, you can not use
  182.    one and the other at the same time.  
  183.  
  184.         byte bigbuf[ 8192 ];
  185.         byte smallbuf[ 512 ];
  186.         int templen;
  187.  
  188.         if ( !udp_open( &data, localport, remote, remoteport, NULL) ) {
  189.             printf("Error opening UDP channel");
  190.             exit( 3 );
  191.         }
  192.         /* set the big buffer */
  193.         if ( sock_recv_init( &data, bigbuf, sizeof( bigbuf )) == -1 ) {
  194.             printf("Error setting the receive buffers");
  195.             exit( 3 );
  196.         }
  197.         while ( 1 ) {
  198.             tcp_tick( NULL );           /* got to do this or sock_tick */
  199.  
  200.             /* check for incomming udp data */
  201.             if ( templen = sock_recv( &data, smallbuf, sizeof( smallbuf ))) {
  202.                 /* something received and it was templen bytes long */
  203.             }
  204.         }
  205.         sock_Close( &data );
  206.  
  207.    sock_recv... adds extra code, so it need not be used for simple UDP sockets
  208.    such as BOOTP which expects only a single packet.
  209.  
  210.    See sock_mode checksums below for more interesting notes.
  211.  
  212. -----------------------------------------------------------------------------
  213. UDP Checksums                   (6/5/1991)
  214.    sock_mode can be used to enable or disable checksums for udp sessions
  215.    using the following calls:
  216.  
  217.         sock_mode( &socket, UDP_MODE_CHK );
  218.         sock_mode( &socket, UDP_MODE_NOCHK );
  219.  
  220.    Unlike *some* systems, Waterloo TCP correctly assumes checksums are active
  221.    and allows an application to disable them on the fly as they consider
  222.    appropriate.
  223.  
  224.    Either or both sides may disable or re-enable checksums.
  225.  
  226. -----------------------------------------------------------------------------
  227. TCP Nagle Algorithm             (6/5/1991)
  228.    The Nagle algorithm is now used to collect data.  Nagle is ideally suited
  229.    to programs like TELNET (TCPPORT), etc. which send a lot of small chunks
  230.    of data.  Some programs, like X-Windows, real-time data collection, etc.,
  231.    should turn of the Nagle feature.  Nagle is on by default and should not
  232.    be disabled unless a true problem is experienced.
  233.  
  234.         sock_mode( &socket, TCP_MODE_NONAGLE ); /* turns it off */
  235.         sock_mode( &socket, TCP_MODE_NAGLE );   /* re-enables it */
  236.  
  237. -----------------------------------------------------------------------------
  238. getdomainname Changes           (6/5/1991)
  239.    getdomainname always took a string and length parameter, just like UNIX.
  240.    Now, if the length is zero, getdomainname just returns the pointer to
  241.    a system copy of the domainstring.
  242.  
  243. -----------------------------------------------------------------------------
  244. gethostname sethostname Changes (6/5/1991)
  245.    gethostname and sethostname are now available.  They work identically to
  246.    get/setdomainname() (as enhanced above).  The host name can either be set
  247.    via the WATTCP.CFG file or via bootp.
  248. -----------------------------------------------------------------------------
  249.  
  250. sock_PreRead addition           (4/26/1991)
  251.  
  252.    int sock_PreRead( void *s, byte *dp, int len );
  253.  
  254.    Some situations arise where it would be nice to read data without causing
  255.    it to disappear from the socket's buffer.  Usually that means double
  256.    buffering.  sock_PreRead works exactly like sock_FastRead, except it does
  257.    not remove the read data from the data buffers.  The returned value is the
  258.    number of bytes transferred, 0 for no data waiting, or -1 on a socket
  259.    error.
  260.  
  261.    This function is intended for special cases which are not easily performed
  262.    using other methods.
  263.  
  264. -----------------------------------------------------------------------------
  265.  
  266. sethostid addition              (4/26/1991)
  267.  
  268.    longword sethostid( longword ip );
  269.  
  270.    This function sets the system's default ip address.  Changing the ip address
  271.    will destroy existing TCP and UDP sessions.  You should close all sockets
  272.    before calling this function.  The passed ip address is always returned.
  273.  
  274.    This function is low level and rarely useful to an application programmer.
  275.  
  276.    main()
  277.    {
  278.        longword ip = 0x80010101;   /* 128.1.1.1 */
  279.        char buffer[ 512 ];
  280.  
  281.        sock_init();
  282.        sethostid( ip );
  283.        printf("IP address has been set to %s\n\r",
  284.            inet_ntoa( buffer, getipaddr() );
  285.    }
  286.  
  287. -----------------------------------------------------------------------------
  288.  
  289. setdomainname addition          (4/26/1991)
  290.  
  291.    char *setdomainname( char *string);
  292.  
  293.    The domain name returned by getdomainname and used for resolve() is set to
  294.    the value in the string passed to setdomainname().  Note that changing the
  295.    contents of the string after a setdomainname() call may or may not change
  296.    the value of the system domain string and is not recommended.  You are
  297.    recommended to dedicate a static location which will permanently hold that
  298.    name.
  299.  
  300.    setdomainname( NULL ) is an acceptable way to totally remove any domain name
  301.    and subsequently resolves will not attempt to append a domain name.
  302.  
  303.    The passed string is always returned, as demonstrated below.
  304.  
  305.    This function is low level and rarely useful to an application programmer.
  306.  
  307.    #include <stdio.h>
  308.    #include <tcp.h>
  309.    char buffer[ 512 ];  /* use a static or a calloc, do not place the name
  310.                            in a local variable on the stack, it may get lost! */
  311.    main()
  312.    {
  313.        sock_init();
  314.        puts("Enter a new domain");
  315.        gets( buffer );
  316.        printf("Was using %s\n\r", getdomainname());
  317.        printf("Now using %s\n\r", setdomainname( buffer ));
  318.  
  319.        setdomainname( NULL );
  320.        puts("Now using no domain name");
  321.    }
  322.  
  323. -----------------------------------------------------------------------------
  324.  
  325. _arp_resolve addition           (4/26/1991)
  326.  
  327.    _arp_resolve( longword ina, void *ethap)
  328.  
  329.    Given an ip address (ina), find the hardware address.  If ethap is non-NULL,
  330.    place the hardware address in the buffer pointed to by ethap.
  331.  
  332.    Each call to _arp_resolve checks a local cache to see if we already know
  333.    the hardware address.  If no entry exists for that IP address, steps
  334.    are taken to find a hardware address.  If the ip node is on our subnet,
  335.    an ARP request is broadcast, otherwise _arp_resolve is called recursively
  336.    to find the address to the gateway.
  337.  
  338.    Socket opens intrinsically call _arp_resolve and place the hardware address
  339.    in the socket structure so they are no longer dependant upon existance in
  340.    the cache.  This means existing tcp and udp sessions do not automatically
  341.    reconfigure if a new route is found to the remote host, but this is typical
  342.    of pc implementations and is quite reasonable.
  343.  
  344.    Programs which wish to force the hardware address to be in the arp cache
  345.    need only specify the ip address and NULL for the ethap buffer.
  346.  
  347.    Returns 1 on success or 0 if the ip address could not be resolved.
  348.  
  349.    This is a special use function and is rarely necessary for user
  350.    applications.
  351.  
  352. -----------------------------------------------------------------------------
  353.  
  354.