home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / lanlib / lantest.txt < prev    next >
Encoding:
Text File  |  1994-06-30  |  26.8 KB  |  492 lines

  1. ; LANTEST.TXT -- Documentation for LANTEST
  2. ; Copyright (c) 1994 by Allen Brunson  version 1.00  06/30/94
  3.  
  4.  
  5. ******************************************************************************
  6. *                                                                            *
  7. ***  Trademarks                                                            ***
  8. *                                                                            *
  9. ******************************************************************************
  10.  
  11. Borland is a registered trademark of Borland International, Inc.
  12.  
  13. Microsoft and MS-DOS are registered trademarks and Windows is a trademark
  14. of Microsoft Corporation.
  15.  
  16. Netware and Novell are registered trademarks and IPX is a trademark
  17. of Novell, Inc.
  18.  
  19.  
  20.  
  21. ******************************************************************************
  22. *                                                                            *
  23. ***  Introduction                                                          ***
  24. *                                                                            *
  25. ******************************************************************************
  26.  
  27. LANTEST is a fairly basic program that nonetheless demonstrates all the
  28. procedures necessary to make LANLIB work effectively.  It allows up to 30
  29. users at PCs on a network to exchange messages in real-time (but could be
  30. made to support a more or less unlimited number by changing the define
  31. USERTOTAL in LANTEST.H).  It displays a large quantity of messages about its
  32. operation so as to give the potential NETLIB user a feel for what is going
  33. on.  It is far from bulletproof; a great many optimizations and "sanity
  34. checks" that would have gone into a production program have been omitted to
  35. keep the source code relatively simple.
  36.  
  37.  
  38.  
  39. ******************************************************************************
  40. *                                                                            *
  41. ***  Compiling LANTEST                                                     ***
  42. *                                                                            *
  43. ******************************************************************************
  44.  
  45. The following source files pertain solely to LANTEST:
  46.  
  47.  LANTEST.C    Main LANTEST source file
  48.  LANTEST.H    Defines for LANTEST
  49.    INPUT.C    Keyboard input and input processing routines
  50.  NETWORK.C    High-level IPX routines
  51.  PROCESS.C    Miscellaneous processing routines
  52.    VIDEO.C    Rudimentary screen functions
  53.  
  54. Like any other LANLIB-using program, LANTEST uses the following files:
  55.  
  56. LANLIBSC.LIB  LANLIB routines for the Small and Compact memory models
  57.   LANLIB.H    Defines for LANLIB
  58.   LANCFG.H    Configuration parameters for LANLIB
  59.  LANUTIL.C    Optional routines for dealing with IPXADDRFULL structures
  60.  
  61. Create a project or make file that includes all the .C files and the proper
  62. .LIB file.  LANTEST was designed as a small model program, but can be made to
  63. work in any memory model (well, almost any memory model -- see below) by
  64. including a different .LIB file and changing the memory model check near the
  65. top of LANTEST.H.
  66.  
  67. LANLIB and LANTEST have been tested with Borland's Turbo C++ v1.0 and v3.0
  68. and Microsoft's C++ v8.0.  They work fine with all of these, except that the
  69. Tiny model doesn't work with Microsoft C; its linker says that far segment
  70. accesses are not allowed in that model.
  71.  
  72. While tweaking the program to work with Microsoft C, I couldn't find library
  73. functions to do certain things I wanted to do, so rather than writing my
  74. own functions, I just left those parts out.  Specifically, when compiled
  75. with a Microsoft compiler, LANTEST will not be able to scroll the upper
  76. part of the screen (it simply erases it instead), it won't wait a variable
  77. length of time before sending ping responses, and it is not able to set
  78. screen colors.
  79.  
  80. An already compiled version of the demo is given as LANTEST.EXE.
  81.  
  82.  
  83.  
  84. ******************************************************************************
  85. *                                                                            *
  86. ***  Running LANTEST                                                       ***
  87. *                                                                            *
  88. ******************************************************************************
  89.  
  90. LANTEST should be run on two or more PCs, but will minimally function on only
  91. one.  If you have the full version of LANLIB, the PCs involved can be on
  92. any network segments in an internetwork; if you have the shareware version,
  93. then the PCs must be on the same segment.
  94.  
  95. Each PC must at minimum have the IPX TSRs loaded; it doesn't matter whether
  96. NETX or VLM is loaded or not.  If you do have a "full" network, including a
  97. NetWare server, it might be easiest to copy LANTEST.EXE into a subdirectory
  98. on the server and run it from there.  On the other hand, you might wish to
  99. copy LANTEST.EXE to each individual PC's hard disk and unload NETX or VLM,
  100. just to convince yourself that LANLIB really does work without a server.
  101.  
  102. When started, LANTEST draws a box around most of the screen, leaving a single
  103. line free at the bottom for entering commands.  If your display is in a text
  104. mode that has more than 25 lines, LANTEST will adjust itself accordingly;
  105. since it can display up to several lines of information for each packet
  106. transaction, it needs all the lines it can get.  The utility LINE50.COM is
  107. included to put VGA displays into 50-line mode (or EGAs into 43-line mode);
  108. you can run this before LANTEST if you wish.
  109.  
  110. LANTEST initializes LANLIB with a call to ipxStart().  If the IPX driver
  111. isn't loaded, you'll get an error message to that effect; the program can't
  112. continue.  If the IPX driver was located in memory, LANTEST will display the
  113. local PC's network address, a reminder that F1 will produce a help screen,
  114. and instructions to use the NAME and PING commands to get started (or NAME,
  115. ROUTE, and PING, if you've got the full-blown version).
  116.  
  117. You can press F1 or enter the command HELP (or H) at any time to get a list
  118. of commands and keys recognized.
  119.  
  120. Enter "NAME Allen" (without the quotes), replacing my name with yours.
  121. The program will tell you that it has set your name.
  122.  
  123. If you've got a registered version of LANLIB that includes the router-finder,
  124. next type ROUTE to update the program's network table.  This might take
  125. awhile; you can press Esc to abort.  After the route-find is complete, you
  126. can type NET to get a list of all networks that were discovered.  If you
  127. enter a filename after NET, then it will also write the information to a
  128. file.
  129.  
  130. Next enter PING, which will cause LANTEST to broadcast an "are you there?"
  131. request to all potential users.  (If you do the PING before ROUTE, then
  132. LANTEST will only know about its own network segment at that point and
  133. therefore will only ping locally.)  Other copies of LANTEST will respond with
  134. "Yes, I'm here" packets, sending the name of the person along with the
  135. message.  LANTEST waits for a random amount of time up to one second before
  136. sending "Yes, I'm here" responses to keep the copy of the program doing the
  137. asking from being deluged with replies all arriving at the exact same
  138. instant.
  139.  
  140. You should get messages onscreen indicating received ping responses.  Wait
  141. at least a second for the activity to die down.  Then enter DISPLAY to
  142. show a list of all users that were found and the IPX addresses of their PCs.
  143. The numbers in the "Rcv" and "Snd" columns indicate the maximum number of
  144. receive and send ECBs that each machine has ever used up to this point.
  145. The number in the "Time" column is the estimated time it takes to send a
  146. packet to that user, in IBM PC clock ticks (about 1/18th of a second); this
  147. information is returned by the ipxAddrImmed() procedure.  The machine you are
  148. using is always first in the list and indicated by an asterisk.
  149.  
  150. The simplest command you can use is BROADCAST [message], which sends a
  151. message to all users that the program knows about.  (Despite the name, it
  152. does NOT broadcast the message to address FFFFFFFFFFFFh; this is considered
  153. a sloppy programming technique.)  Note that this has the effect of updating
  154. all receivers' user lists with your name and ECB usage statistics, if their
  155. information is out of date.
  156.  
  157. The MESSAGE [usernum] [message] command will send a message to only one user.
  158. You must enter the user's number from the list generated by DISPLAY.
  159.  
  160. An interesting feature of LANTEST is that it will try to interpret the text
  161. of a received broadcast message or directed message as if it were a command.
  162. If it's not a valid command, no error will be displayed; it is assumed the
  163. message was only informational.  If the message is a valid command, then
  164. the receiving copy of LANTEST will act on it.  Therefore, all running copies
  165. of LANTEST can be controlled from any one copy.
  166.  
  167. The FLURRY command is used to send out flurries of packets.  FLURRY ON will
  168. begin the packet flurry.  If at least one copy of LANTEST is sending
  169. flurries, then all PCs that it knows about will receive the flurries and
  170. will display the total number of flurry packets received every time that
  171. 1,000 of them have arrived.  Try issuing the command BROADCAST FLURRY ON,
  172. which will send the command to all PCs running LANTEST, and see how badly
  173. your network bogs down.  FLURRY OFF turns off the flurry packets;
  174. BROADCAST FLURRY OFF will instruct all PCs to stop.  FLURRY RESET resets
  175. the number of received flurry packets to zero.
  176.  
  177. STAT displays the maximum number and total number of send and receive ECBs.
  178. (The maximums are also displayed in the DISPLAY listing.)  You can reset
  179. these values to zeroes with STAT RESET.
  180.  
  181. If one user exits LANTEST, it doesn't send any kind of notification to other
  182. users that it has left, so their user tables will be out of date.  Issuing
  183. another PING will clear things up.  This could have been taken care of by
  184. the program itself, but this is only a demo, after all.
  185.  
  186. When you're finished playing with LANTEST, enter QUIT to return to DOS.
  187.  
  188.  
  189.  
  190. ******************************************************************************
  191. *                                                                            *
  192. ***  Dissecting LANTEST                                                    ***
  193. *                                                                            *
  194. ******************************************************************************
  195.  
  196. There are several source files necessary for LANTEST, but almost all of them
  197. involve typical program tasks like printing text to the screen, managing
  198. and processing user input, and so on, and can be safely ignored by the
  199. reader who merely wants to learn how to use LANLIB.
  200.  
  201. LANTEST.H contains defines for LANTEST, including the definition of the
  202. USER structure that holds information on all known users, and struct
  203. LANTESTPKT, which is the structure for the data in all packets that LANTEST
  204. sends and receives.
  205.  
  206. VIDEO.C contains rudimentary screen functions.  It has routines to do tedious
  207. video tasks like drawing the box around the main window, scrolling the top
  208. portion of the screen, and so on.  All video output to the top window is done
  209. via calls to message().
  210.  
  211. INPUT.C is responsible for reading keyboard input and processing command
  212. lines once the user has finished entering them.  Two of its procedures,
  213. getKeys() and cmdProcess(), are in the program's main loop.
  214.  
  215. PROCESS.C contains miscellaneous procedures not very interesting to the
  216. potential LANLIB user.  demoStart() checks to make sure that the DOS version
  217. is at least 3.0, the minimum required for LANLIB.  The one IPX-related
  218. procedure it contains is err(), a routine that will display a message
  219. onscreen for each possible LANLIB error code.
  220.  
  221. NETWORK.C is the real heart of LANTEST.  For the reader interested in
  222. learning how to use LANLIB, this is the file that deserves closest scrutiny.
  223. It is initialized with a call to nStart(), which calls ipxStart() to start
  224. up LANLIB.  If the define DEBUG in LANTEST.H is un-commented, then nStart()
  225. passes the address of an IPXDATA structure, ipxData, to ipxStart() to use as
  226. the communication data.  This is useful for debugging, as you can inspect the
  227. many fields of the IPX structures to see what is going on.  If DEBUG is not
  228. defined, then nStart() instead calls malloc() to allocate a block of memory
  229. to use for communication data.
  230.  
  231. Next nStart() calls ipxAddrLocal() to get the address of the PC it is running
  232. on and saves the address as the first entry in its user structure.  Then it
  233. copies its address to ipxAddrBroad, an IPXADDRFULL, and uses the utility
  234. routine ipxAddrBrd() to set the node and immediate address fields to
  235. FFFFFFFFFFFFh, which makes the address suitable for broadcasting on its local
  236. segment.  (This step is technically only necessary for single-segment
  237. programs, but even the router-finding version of LANTEST is restricted to
  238. a single segment until ipxRouteFind() is called.)
  239.  
  240. Here is LANTEST's main() procedure, from LANTEST.C:
  241.  
  242. byte main(void)                                    // Begin main()
  243.   {
  244.     demoStart();                                   // Start up subsystems
  245.  
  246.     while (!endProgram)                            // Main program loop
  247.       {
  248.         getKeys();                                 // Get input keys
  249.         cmdProcess();                              // Process commands
  250.         while (ipxRecvChk()) recvPacket();         // Process packets
  251.         sendFlurry();                              // Send flurry packets
  252.         sendErr();                                 // Check for send errors
  253.       }
  254.  
  255.     demoStop();                                    // Stop subsystems
  256.  
  257.     return FALSE;                                  // Return errorlevel 0
  258.   }                                                // End main()
  259.  
  260. It merely calls demoStart(), then calls six major procedures in a loop until
  261. endProgram is TRUE, then calls demoStop().
  262.  
  263. The procedure getKeys() processes no more than one key at a time.  This
  264. allows other tasks to run while the user is entering command lines.  The
  265. procedure cmdProcess() will return immediately unless the user has just
  266. pressed Enter, ending a command line, or unless there is a message to be
  267. interpreted as a command.  If a command line is ready, cmdProcess() will
  268. parse it and call the procedure necessary to execute it.
  269.  
  270. The procedure recvPacket(), in NETWORK.C, processes one received packet.
  271. Note that the main loop is written so as to call recvPacket() as many
  272. times as necessary to clear out all received packets.  This slows down
  273. other processes somewhat but ensures that the receive ECBs should almost
  274. never completely fill up.
  275.  
  276. recvPacket() checks the first word in the packet's data, looking for
  277. LANTEST's signature.  If it doesn't find it, it displays an error message and
  278. does nothing further with the packet.
  279.  
  280. If the signature is okay, it checks the packet type (the second word in the
  281. packet) to see if it's a flurry packet.  If it is, it increments the count
  282. of flurry packets.  If the count is evenly divisible by 1,000, it displays
  283. the flurry packet total.
  284.  
  285. If it's not a flurry packet, it displays a message saying that it got the
  286. packet, along with the address of the sender.
  287.  
  288. Since the signature in the packet was correct, the sender has now been
  289. verified as a bona-fide LANTEST user, so userSave() is called to add this
  290. user to the user table (or to update existing information).  The user's
  291. address, name, and statistics are saved.
  292.  
  293. LANTEST uses only five types of packets: ping, ping response, broadcast,
  294. message, and flurry.  A number indicating the packet type is stored in
  295. the packet as its second word-sized variable.  Based on this information,
  296. recvPacket() calls one of four routines to process the packet in some way
  297. (flurry packets will have already been dealt with).
  298.  
  299. If the packet was a broadcast or message, then recvBroadcast() or
  300. recvMessage() is called, respectively.  These packets are quite easy to deal
  301. with; these procedures simply print "Broadcast from <name>:" or "Message from
  302. <name>:" and then the text of the message, which is stored as the fourth and
  303. final field in the data packet.  Then the text of the message is copied to
  304. cmdStr, the command string, and inputFlag is set to 2, which means "remote
  305. input received."  The next time through the main loop cmdProcess() will
  306. notice this and try to interpret the message as a command.
  307.  
  308. Receiving a ping packet requires the most processing and is done by
  309. recvPing().  Since the ping will be received by possibly a great many other
  310. copies of LANTEST, all of which are going to send back a ping response, the
  311. sender could be deluged with packets, its receive buffers might fill up
  312. before it could process all the replies, and so some replies might be lost.
  313. To keep this from happening, recvPing() waits for a random amount of time, up
  314. to a second, before calling ipxSendPkt() to send a reply to the address that
  315. the ping was received from.  Note that when LANTEST sends a ping, it receives
  316. a copy just the same as everybody else, so this procedure checks to see if
  317. the sending address is the same as this PC; if so, it doesn't send a ping
  318. response.
  319.  
  320. If the packet received is a ping response, recvPingResponse() is called.
  321. The purpose of a ping response is to make note of the sender in the user
  322. table, and recvPacket() has already done this, so recvPingResponse() does
  323. nothing but print a message onscreen.
  324.  
  325. routeFind() is called when the user enters the ROUTE command.  It calls
  326. ipxRouteFind() to find networks, and uses routeWait() as its procedure to
  327. be called while waiting for ipxRouteFind() to complete.  If DEBUG is defined,
  328. it uses a static structure for the network info; if not, it uses malloc() to
  329. get a block of memory instead.  The information that it gathers is only
  330. used by sendPing(), described below.
  331.  
  332. The procedure sendFlurry() is called in the main loop.  If flurry mode isn't
  333. turned on, it does nothing.  If flurry mode IS on, it sends one (but ONLY
  334. one) flurry packet to a user in the user table.  Then it increments its
  335. user number for the next call.  If the current user number points to a
  336. slot in the user table that is unused, sendFlurry() does nothing; given
  337. that most of the slots in the 30-user table will be probably be free,
  338. sendFlurry() wastes a lot of time.  This was done intentionally.
  339.  
  340. The procedure sendErr() is called repeatedly in LANTEST's main loop.  It
  341. checks for send errors with ipxSendChk(); if there is one, it uses
  342. ipxSendErr() to retrieve the packet that couldn't be sent and the address it
  343. should have been sent to.  If there's an error, sendErr() does nothing
  344. but print a message; a "real" program should either retry the send or take
  345. other action as necessary.
  346.  
  347. sendBroadcast() is used to broadcast messages to all users.  It does NOT
  348. do so by sending the message to node address FFFFFFFFFFFFh, as you might
  349. guess; it sends the message to each user in its user table instead.  This
  350. is more work -- it has to do a send for every user in the table, instead of
  351. just one send to its "broadcast" address (or a send to all of its broadcast
  352. addresses, if the router finder has been called) -- but this is the proper
  353. way to go about it.  IPX broadcasts are received by every PC on the network,
  354. whether they're running your program or not.  Therefore, each and every IPX
  355. driver on every machine on the network will receive a broadcast and have to
  356. spend precious CPU cycles determining that there isn't a program running at
  357. that machine that wants it.  Therefore, you should only use broadcasts when
  358. absolutely necessary, which is normally only while you're looking for other
  359. PCs running your program.  If you fail to follow this rule, the network
  360. managers at large sites where your program is run will be very unhappy with
  361. you.
  362.  
  363. Since sendBroadcast() does a bunch of sends in quick succession, it really
  364. should be written so that it checks the return value from ipxSendPkt() to
  365. see if all available send ECB/packet pairs are in use, and if so, it should
  366. wait a short period of time, say 20 milliseconds, perhaps using the time
  367. to call ipxSendErr() to clear out any errors, and then try again.  It doesn't
  368. do this as written.
  369.  
  370. sendMessage() is pretty much like sendBroadcast().  It's a little simpler
  371. in that it only has to send to one user, and a little more complicated in
  372. that it has to collect a user number and check to make sure that the number
  373. is valid.
  374.  
  375. sendPing() is called when the user issues the PING command.  It clears its
  376. user tables of all entries (except the PC it is running on, of course) and
  377. then broadcasts a ping packet.  A "ping packet," for the purposes of this
  378. program, is nothing but one that has its packet type set to the numeric
  379. value that means "ping packet."  Broadcasts should be avoided wherever
  380. possible, because every PC on a network segment will receive them, and the
  381. IPX driver at each PC will have to process them whether that PC has a running
  382. program that wants the packet or not.  In this case a broadcast must be used,
  383. since at this point it is not known who the other users are, so they can't
  384. be targeted individually.  If the router finder is installed and it has been
  385. called, then sendPing() will broadcast to all known networks; if not, then
  386. it will broadcast only on its local network.
  387.  
  388.  
  389.  
  390. ******************************************************************************
  391. *                                                                            *
  392. ***  Thoughts on Robust IPX Programs                                       ***
  393. *                                                                            *
  394. ******************************************************************************
  395.  
  396. There are a lot of things that can go wrong when using IPX.  You really
  397. should take these things into account when designing an IPX-using program.
  398.  
  399. Among the most serious of IPX programming issues, and one that LANTEST
  400. doesn't tackle at all, is the fact that IPX doesn't guarantee delivery.
  401. In the context of LANTEST, a lost packet could mean that a broadcast message
  402. doesn't arrive at all users' PCs, or that a ping response might be lost and
  403. so someone's user table would be incorrect.  This isn't very serious in a
  404. demo, but it could be quite disastrous in some production programs.
  405.  
  406. To make the process of keeping track of users more bulletproof, it would be a
  407. good idea to have the program send a message to all users just before it
  408. terminates.  Then they could all take that user out of their user table
  409. without having to re-ping to clear things up.
  410.  
  411. When pinging, it would be advisable to broadcast a ping, wait a second or two
  412. to receive replies, and then broadcast a second and third ping.  Given IPX's
  413. claimed delivery rate of 95 percent, the odds against missing somebody that
  414. way are quite remote.
  415.  
  416. To go even further, a ping probably shouldn't first clear out the user table,
  417. but instead mark everyone as "suspect."  When a reply is received from
  418. someone, that makes them a user in good standing.  If one or more PCs in the
  419. table still haven't been heard from at the end of three pings, it's a good
  420. bet that the user in some way exited the program without its being able to
  421. send a message that it was terminating.  An error message stating that a
  422. certain user has been "lost" might be appropriate.
  423.  
  424. When sending messages, it would be a good idea for the receiver to send back
  425. a reply saying, "yes, I got it," perhaps also sending a checksum of the
  426. message.  If the sender doesn't get a reply in a reasonable amount of time,
  427. within a second or so, then it can display an error message stating that
  428. the message wasn't received or try again.  The amount of time to wait before
  429. timing out depends on the network itself.
  430.  
  431. Another serious issue is the fact that IPX packets may not arrive in the
  432. same order you sent them in.  They probably will, especially on small
  433. networks, but in larger networks there may be more than one route between
  434. any two PCs, and based on network traffic or other criteria, a router might
  435. send a packet one direction one time and another direction the second time;
  436. this can certainly lead to out-of-order packets.
  437.  
  438. Therefore, if you're sending a message that's comprised of more than one
  439. packet, all packets should contain some kind of sequence number.  That way
  440. the receiver can reconstruct the message as necessary.
  441.  
  442. Network traffic can vary greatly from network to network and from minute
  443. to minute.  Yours will almost certainly not be the only program running
  444. on the network.  As you are writing your program, if at all possible take
  445. into account the fact that network throughput will not remain constant, and
  446. keep network traffic to a minimum as much as possible.
  447.  
  448. Some sort of handshaking will be necessary to get faster machines to
  449. properly communicate with slower machines.  Chances are excellent that a
  450. fast '486 will be able to send enough packets to a slow '286 to overrun its
  451. receive ECBs very quickly.
  452.  
  453.  
  454.  
  455. ******************************************************************************
  456. *                                                                            *
  457. ***  Configuring LANLIB for LANTEST                                        ***
  458. *                                                                            *
  459. ******************************************************************************
  460.  
  461. LANLIB is configured for a specific program via defines in LANCFG.H.  The
  462. defines were not changed to reflect the needs of LANTEST because I wanted to
  463. leave them at reasonable values for most programs.  However, it will be
  464. instructional to consider how these values should have been set for this
  465. program.
  466.  
  467. The value of IPXSOCKET should of course be set to some semi-random value
  468. between 4000h and 7FFFh, just as with any other IPX-using program.  The user
  469. wishing to make her program particularly bulletproof would set the socket
  470. number in a configuration file so it could be changed if there is a conflict.
  471.  
  472. The value IPXNETCNT should be set to something small, since this is a demo; 6
  473. would probably be a good value.
  474.  
  475. IPXDATASIZE is an easy one.  The largest packet that LANTEST ever sends
  476. contains 92 data bytes, when doing a message broadcast or a message send
  477. (ping packets and responses and flurries are smaller), so IPXDATASIZE
  478. should be set to 92.
  479.  
  480. IPXRECVCNT should be set to a fairly large number, since flurries can
  481. obviously fill up receive ECBs very quickly, especially when fast machines
  482. send to slower ones.  Since the size of each individual packet buffer is very
  483. small, and there's no performance penalty imposed by having lots of
  484. ECB/packet pairs, this number should be set very high, probably all the
  485. way up to the maximum, 250.
  486.  
  487. LANTEST only generates multiple sends under one circumstance: when
  488. broadcasting a message to all users.  So the program might have to do as
  489. many as 30 back-to-back sends.  But it's a fair bet that most sends will
  490. complete within microseconds of making the request, so setting IPXSENDCNT
  491. to 10 should be high enough.
  492.