
Commonly Asked Questions and Answers for LWP Toolkit
----------------------------------------------------


Q: Is there WINSOCK support for LWP?

A: It will be available on Netwire in the Fall 1993.   


Q: How do I detect when the remote host has dropped the connection
   unexpectedly?  ie. you pull the plug, or disconnect the network
   cable.

A: Use setsockopt() on the client side to enable KEEPALIVES.  A packet
   with just '?' for data is sent out every 75 seconds.  The other
   side should recognize this as a KEEPALIVE packet and send back an
   ACK.  If the client doesn't receive the acknowledgement within
   another 75 seconds the socket will be closed.  Any socket calls you
   make after that will return -1 and have errno=EBADF (as long as
   that function uses the socket descriptor - not things like bcopy()).
   Note that you must call setsockopt() BEFORE connect()!


Q: What if I'm in the middle of a blocking recv() on the client side,
   KEEPALIVES on, and I pull the plug on the remote host.  Will LWP
   close down that socket and return recv() with -1, errno=EBADF?

A: Yes it will close down the socket and recv() returns with -1 but if
   you have the latest tcpip from Netwire errno=ECONNRESET instead of
   EBADF.  (Type "version tcpip" and you get something like this:
   ....DOS TCPIP v4.1 (R41-1n, 930727) - version R41-1n or later, say
   R41-1o, is what I mean here.)


Q: I am using select() and the socket is always ready for writing,
   and showing an exception.  Why?

A: These features were not implemented in tcpip R41.  In tcpip v4.1
   R41-1n (or later) we have support for the write descriptors.


Q: What is the difference between write() and send()?

A: None in the original tcpip v4.1 (the one that came on the diskettes), 
   because we didn't support any flags on the send().  In v4.1 R41-1f
   we added support for sending Out Of Band data but that is the only 
   difference.   The latest LWP41 patch on Netwire includes features 
   added in earlier versions such as 41-1f.


Q: I am writing a DOS client for the UNIX server.  How will I know when
   a client has gone down?

A: When the client closes its socket normally the server should not
   have a problem.  It's when you Ctrl-C out of the DOS tcpip app.
   that you get a surprise.  In the DOS/LWP world sockets are not tied
   in with the application and are not closed by DOS when you kill the
   application like this.  So even if you are running KEEPALIVES on
   your UNIX the LWP tcpip will still have those sockets open and ACK
   the UNIX's KEEPALIVES.  You need to add an interrupt handler for
   Ctrl-C to your LWP app and from there close all open sockets.  You
   may also want to look at the _abort_oper() function.


Q: What is the maximum length of buffer I should be able to write 
   with one call to sowrite() ?

A: 32K but you will need to increase the Mempool in your net.cfg.
   Some data is buffered by the tcpip stack and with the default
   Mempool of 4096 you can write about 12K at once.  Mempool is also
   used to store outgoing data so once you increase that you can write
   up to 32K at once, providing the remote host is advertising a
   Window size of at least 32K.  The default window size in our tcpip
   is only 2880 (bytes).  If you get tcpip version v.4.1N (R41-1n)
   from Netwire then you can increase the Window size to 32767 with a
   tcp_window statement in the net.cfg


Q: How are LSL Buffers related to data flow?
  
A: These are buffers for incoming data.  Increasing the number of
   buffers should increase the number of bytes you can read in one
   soread() call, provided you have increased your Window size, and
   there's that much data there to be read...


Q: What is the maximum number of sockets I can use at once?

A: 128 tcp + 64 udp.  You may notice that if you open a socket and
   make a connection, then close the socket that descriptor doesn't
   become available until the other side has closed its socket or 2
   minutes have expired.  If you use LWPCON you'll see the socket in a
   CLOSING state.  This is part of the TCP protocol.  Read Comer's
   Internetworking with TCP/IP Volume II page 194 for an explanation.
  

Q: When I restart my server I get "Address already in use" from
   bind().

A: First you need to close the original socket that is using that port
   number.  If you hit Ctrl-C to quit the program and didn't write
   your own interrupt handler to close that socket, then its probably
   still in a LISTENING state. (Use LWPCON to see the state of your
   sockets.)

   You could do: for (i=0; i<128; soclose(i), i++); before creating
   the socket and then do setsockopt(REUSEADDR) before the bind.  Now
   you should be able to reuse that port.  Of course this would also
   close all other tcpip apps that were running.
 

Q: How do I know when my connect() has completed if I'm using
   non-blocking I/O ?

A: Keep calling connect() until errno=EISCONN.  The first call to
   connect() will put errno=EINPROGRESS, then you'll get
   errno=EALREADY and finally errno=EISCONN (if the connection
   succeeds).


Q: How long does it take for a blocking connect() to timeout? 

A: 75 seconds.  Not configurable but if you use non-blocking connects
   with time(), you can loop on connect()s until errno=EISCONN, or x
   seconds have passed.  In Windows use GetTickCount() instead of
   time().
  

Q: What is the maximum number of pending asynchronous calls I can have?

A: 16 total for all Windows apps, 16 per app in DOS.  An ENO_RCBS error
   may indicate you've exceeded 16.


Q: Is there a way to cancel pending asynchronous calls?

A: Yes, close that socket.


Q: What socket options does LWP4.1 support?

A: KEEPALIVE and REUSEADDR.


Q: How can I broadcast a message?

A: Open a UDP socket and then sendto() to your network's broadcast
   address.
	addr.sin_addr.s_addr = inet_addr("255.255.255.255");
	rc = sendto (s, buffer, BUFFER_SIZE, 0,
                     (struct sockaddr *)&addr, sizeof(addr));


Q: We wrote an application for LWP4.01, will it run on LWP4.1?

A: Yes, provided you did not access unsupported/undocumented
   structures in 4.01.  Although 4.1 uses PATH statements in the
   net.cfg to find files in \NET\TCP directory (ex. hosts file), if
   your application was compiled with 4.01 you still need to 'set
   excelan=c:\xln'.  For Windows apps add 'Root=c:\xln' to the top of
   your lwp.ini.


Q: I get "symbol not defined" errors from the compiler when I do:
   ioctl(FIONBIO).

A: Use soioctl() with Borland.  They have their own ioctl() so we
   renamed ours.


Q: Do any of the socket API functions use DOS interrupt 21?

A: Only the host database functions (gethostbyname, getnetbyname,
   rhost...).


Q: Is there a way for a Windows program to check if vtcpip.386 has
   been loaded?

A: Not directly.  The best you can do is to use the Windows INI
   routines to see if there is a device=vtcpip.386 in system.ini.


Q: Can I do ICMP ?

A: No, we do not support raw sockets.


Q: I'm having trouble writing an FTP or TELNET client.

A: Look for examples and specs in the following:
   1. Internetworking with TCP/IP by Douglas Comer, Prentice Hall.
   2. UNIX Network Programming by W.Richard Stevens, Prentice Hall.
   3. The RFCs (Request for Comments).  These are the set of documents
      that define the Internet Protocols.  Appendix 1 in Comer tell you
      how to get these.  nic.ddn.mil is one place for anonymous ftp.

	IP (Internet Protocol)  			RFC 791
	TCP (Transmission Control Protocol)		RFC 793 (0-64 sockets)
	UDP (User Datagram Protocol) 			RFC 768 (0-32 sockets)
	TELNET (Telnet Protocol) 			RFC 854
	FTP (File Transfer Protocol)			RFC 959
	TFTP (Trivial File Transfer Protocol) 		RFC 783
    4. BSD sources are available on the Internet.  Use archie to find
       what you need.


Q: I'm having trouble compiling/linking the sample windows programs
   for Borland's C++.

A: Add them as items to your project.  For instance, to make the
   wtcpserv sample program open a new project and add wtcpserv.c,
   wtcpserv.rc, twlbsock.lib as items in that project.  Linker
   settings: Default Libraries.  Note that the link is NOT case
   sensitive.  If you want to do case sensitive linking, create your
   own import library :
    
    "IMPLIB myimp.lib wlibsock.dll"

   Source code extention should be *.C, not *.CPP.  Specify the path
   for the header files and libraries under Options->Directories.  For
   Windows apps you also need to #define WINDOWS under
   Options->Compiler->Code Generation->Defines.

------------------------------------------------------------------
# Makefile for wtcpserv and wtcpclnt sample programs
# Type:  make -DPROG=wtcpserv
#        make -DPROG=wtcpclnt

$(PROG).exe : $(PROG).obj $(PROG).res $(PROG).def
    tlink /Tw /v /n /c c0ws $&, $&, , twlbsock cws cs import, $&
    rc $*.res
.c.obj :
    BCC -c -ms -v -W -DWINDOWS $<
.rc.res :
    rc -r -iC:\borlandc\INCLUDE $<
-------------------------------------------------------------------

Q: There is no gethostname() function to get my local host's name.
   How can I do this?

A: Do getmyipaddr() followed by gethostbyaddr() or raddr().


Q: Why isn't gethostbyname() finding my resolv.cfg ?

A: It just looks at your local hosts file.  You need to use rhost()
   for DNS.


Q: I'm having trouble using gethostbyname()/gethostbyaddr() in
   Windows.

A: The hostent fields are OFFSETS to the name,address aliases, etc.
   To access the values of those field take the pointer to the hostent
   structure and add the offset. In DOS you get the fields themselves,
   not offsets and can access the values directly.  Here's how you get
   the hostname:
	pHost = (struct hostent far *) GlobalLock(hTemp);
	pHostName = (char far *)pHost;
	pHostName += pHost->h_name;


Q: Does LWP tcpip use the Nagle algorithm?

A: No, as soon as you write any data it is sent (providing other
   party's windows size > 0).
	

Q: How do I find out what local port my socket is using?

A: Do a bind() with your IP address and port number set to 0.  The
   transport will assign you a port number which you can get by then
   calling getsockname().
	
     





