October 31, 1995

DWINSOCK V1.4
-------------

A Windows Socket interface component for use with Borland Delphi.

By  Ulf Sderberg,  ulfs@sysinno.se
    Marc Palmer,    marc@cablenet.net
    Keith Hawes,    khawes@ccmail.com

This is a short description of the DWinSock component for Borland Delphi
that is contained in the file DWINSOCK.ZIP.

A Delphi installable help file is being developed, and will be realesed onto 
the WWW page (http://www.cablenet.net/pages/marc/dwinsock.htm) sometime soon.
For now, the help file supplied will not give you context sensitive Help on 
properties, but does contain (almost) complete information on using DWinsock.

FILE CONTENTS
-------------
wsAPI.PAS       A unit with all of the winsock API. Consolidated from files
                that originally came from PASOCK10.ZIP that have been changed
                (WINSOCK.INC, WINSOCK.IF & WINSOCK.IMP)
dwsError.res    A String Resource containing the translation of error numbers
                to messages.
dwsError.rc     Source for dwsError.res Compile with BRCC -30 dwsError.rc
dwsError.pas    Delphi Unit that contains the constants for dwsError.rc
DWINSOCK.DCR    Contains two component palette bitmaps.
DWINSOCK.PAS    The source code of the component.
DWINSOCK.DCU    The compiled unit.
DWINSOCK.HLP	The Help File

THE COMPONENTS IN DWINSOCK
--------------------------
DWinSock contains two components which are named TClientSocket and
TServerSocket. As the names implies, they are to be used in client or
server applications.

TClientSocket Properties
  --------             Design Time
  Address              address of remote host, a string like '127.0.0.1'
  Host                 name of remote host, a string
  Options              defines the actions the socket will respond to
    csoRead            Respond to Reading
    csoWrite           Respond to Writing
    csoOOB             Respond to Out Of Band data
  Name                 Standard TComponent property
  Port                 port number, an integer
  Service              name of port, a string
  Tag                  Standard TComponent property
  TimeOut              Time out value in seconds (0 for no time out)
  --------             Run Time & read only
  Conn                 current TSocket
  Handle               window handle, used to receive messages from WinSock
  Description          name of underlying WinSock

TClientSocket Events
  OnConnect            Connection is successful
  OnDisconnect         Host disconnected
  OnInfo               Progress notification
  OnRead               Incoming Data
  OnWrite              Write completed
  OnAsyncComplete      Asynchronous lookup completed.

TClientSocket Methods
  Close                Disconnect form the host
  Connected            True when the socket is connected to the host
  LocalHost            Name of yourself
  Open                 Attempt to connect to the Host
  --------             Lookup Functions
  LookupHostByAddr*    Gets a host name from an address
  LookupAddrByName*    Gets a host address from its name (as in_addr)
  LookupAddrByNameStr  Gets a host address from its name (as string)
  LookupPortbyService* Gets a port number from its name
  LookupServiceByPort* Gets a port name from its number
  * Asynchronous version available by prefixing method with ASYNC

TServerSocket Properties
  --------             Design Time
  Address              Address of the client to connect with, '0.0.0.0' for all
  ClientOptions        Defines the actions the socket will respond to
    csoRead            Respond to Reading
    csoWrite           Respond to Writing
    csoOOB             Respond to Out Of Band data
  MaxConnections       Maximum allowable number of connections
  Name                 Standard TComponent property
  Port                 Port number, an integer
  Service              Name of port, a string
  Tag                  Standard TComponent property
  --------             Run Time & read only
  Conn                 The Server's TSocket
  Conns                TList of client sockets
  Handle               Window handle, used to receive messages from WinSock
  Description          Name of underlying WinSock

TServerSocket Events
  OnAccept             Incoming connection accepted
  OnDisconnect         Connection disconnected
  OnInfo               Progress notification
  OnRead               Incoming Data
  OnWrite              Write completed
  OnAsyncComplete      Asynchronous lookup completed.

TServerSocket Methods
  Client               Returns the TSocket of a client in the Conns list
  ClientCount          The number of Clients in the Conns list
  Close                Disconnect form the host
  CloseDown            Close all Connections and server
  Listen               Listen for incoming connections
  LocalHost            Name of yourself
  --------             Lookup Functions
  LookupHostByAddr*    Gets a host name from an address
  LookupAddrByName*    Gets a host address from its name (as in_addr)
  LookupAddrByNameStr  Gets a host address from its name (as string)
  LookupPortbyService* Gets a port number from its name
  LookupServiceByPort* Gets a port name from its number
  * Asynchronous version available by prefixing method with ASYNC


OTHER OBJECTS (TSocket)
-----------------------
Both TClientSocket and TServerSocket are derived from the class TSoskCtrl.
TSockCtrl uses an object called TSocket which contains the connection status
like IP address and port number. TSocket has several methods that you may call
via the Conn property, they are:

  --------      Information
  BytesSent     The number of bytes send from the last Send or Text := string
  InCount       Returns amount of data that can be currently read from the port
  LocalAddress  Returns your address
  LocalPort     Returns your port number for a connection.
  RemoteHost    Returns the remote host name.
  RemoteAddress Returns the remote IP address.
  RemotePort    Returns the remote port number.
  LastError     Returns the last winsock error number.
  SocketID      Returns the Socket handle.
  Connected     Returns TRUE if the socket is connected.
  Parent        Returns the TSockCtrl that owns the socket.
  Addr          Returns the sockaddr_in record for the socket.
  --------      I/O
  Recv          Receive a buffer
  Send          Send a buffer
  Text          Property: Send and receive text from the port:
                Send: Text := 'Send this';
                Recv: Receved_This := Text;
  ReadFlush     Causes the OnRead event to be called until there is no more
                incoming data.

OTHER OBJECTS (the TAsyncInfo class)
--------------------------
The AsyncLookup* methods of TServerSocket 7 TClientSocket return a tHandle.
This handle is used to match the function call with its data when the
OnAsyncComplete event is triggered. There are three descendants of TasyncInfo
they are TAsyncHostInfo, TAsyncServiceInfo and TAsyncProtocolInfo.

TAsyncInfo Properties (Run Time & Read Only)
  --------       Common to all TAsync*Info objects
  Taskhandle     The handle that AsyncLookup* returned
  Error          The Resulting Error for AsyncLookup*

  --------       TAsyncHostInfo
  Name           Host name
  Address        Host Address as a string
  Addr           Host Address as an in_addr
  Info           The Entire HostEnt record

  --------       TAsyncServiceInfo
  Name           Service name
  Port           Port number
  PortStr        Port Number as a String
  Protocol       Protocol Name
  Info           The Entire ServEnt record

  --------       TAsyncProtocolInfo
  Name           Protocol name
  Number         Protocol number
  NumberStr      Protocol Number as a String
  Info           The Entire ProtoEnt record


EXCEPTIONS
----------
If anything goes wrong inside you will get an exception of type ESockError
with
a message indicating what kind of error that cause the exception.

SUMMARY
-------
This was a very brief description of DWINSOCK. As you can see from the source
files it does not at all use all functions of Windows Sockets but it provides
a quick solution to get into WinSock programming with Delphi. And covers
enough of the basics to handle most applications.

NETTIME is an example of using dWinSock, It gets the current time of day from
a time server. NETTIME can be found where you found dWinSock or on the
dWinSock home page: http://www.cablenet.net/pages/marc/dwinsock.htm

You may use DWINSOCK any way you like but don't blame us.

Suggestions may be emailed to any of the folks listed at the beginning of this
document.

------------------------------------------------------------------------------
Revision History
Helpful hints on converting from one version to the next indicated by '>>'
Parts of this code (especially wsAPI.pas) were inspired by WINSOCK.PAS by
Marc B. Manza.
------------------------------------------------------------------------------
  V1.4  The Non-Blocking version
        . Added "vitrual;" to destructor of Tsocket;
        . Added siAccept and added call to Info(siAccept) moved calls to
          Info(siClose) to the socket to catch all closes, added
          Info(siSend) to TSocket.Send, added Info(siRecv) to Tsocket.Recv.
          This should make info notifications work even better.
        . Set Result field in Message record
        . Fix using q instead of nqlen in listen
        . Error handling completely changed. Added LastError and SError to
          TSocket.
        . Added siNoSuchSocket to notify programmer that a socket message
          arrived for a socket that does not exist (Trumpet will send a
          Close message after the socket is closed by the server.)
        . Changed DoAccept, TServer.OnSockMsg and it's FindConn to return
          TSocket and help with handling siNoSuchSocket.
        . DWSError.res eliminates error.inc. used Errno.rc as a start.
          (Compile with BRCC -30 DWSError.) Created wsAPI to replace
          winsock.inc, winsock.if and winsock.imp. Changed
          Dwinsock.wsAPICall to wsAPI.wsAPICall through out dWinSock.
          >> You will need to add wsAPI to your uses clauses.
        . Moved Timout and OnTimeOut to protected in TSockCtrl and
          Published in TClientSocket.
        . Move OnDisconnect, OnRead & OnWrite to Protected in TSockCtrl,
          and Publish them in TServerSocket & TClientSocket
        . Changed TSockInfoEvent to also pass a TSocket.
           >> Change your code to match the new Parameters (Sender : TObject;
              icode : TSockInfo; Socket: TSocket)
        . Added virtual functions DoXXX to match all OnXXX events. This
          will allow descendants of TSockCtrl to handle events in their own
          way. Changed Info to DoInfo
        . Corrected bug in TSockCtrl.Reverse.
        . In both OnSockMsg procedures, the err variable is saved in the
          sockets FLastError field. This means that in OnConnect, you can
          check for connection errors (no more false connections in
          DWinSock).
        . Changed all hard tabs to spaces.
        . Moved DoInfo to after we have a valid Socket in the servers
          DoAccept
        . Moved TSocket data from Public to Protected and provided read
          only properties.
        . Changed refrences to FSocket to SocketID FParent to Parent,
          FConnected to Connected, and FAddr to Addr.
          >> Change .Fsocket to .FSocketID in your code.
        . Changed TSockCtrl to set the Port when you set the Service and to
          set the Service when you set the port.
        . Added a CM_SOCKCLOSE message to handle cleanup of sockets
          (Freeing them in the case of the server). This will avoid the
          possibility of having a socket being freed before the close
          process is complete. CM_SOCKCLOSE causes CBSockClose to be
          called.
        . Removed TClientSocket.CBSockClose since it does noting like it's
          parent TSockCtrl.CBSockClose;
        . Added TSocket.RecvFlush to Force all data to be sent. Added a
          call to RecvFlush in TSocket.Close;
        . Made substantial changes to TSockCtrl to stop using blocking
          calls while still maintaining the perceived synchronous nature of
          the blocking getXbyY calls. Methods affected: Tsocket.RemoteHost,
          TSockCtrl.Reverse, TSockCtrl.LookupName, TSockCtrl.LookupService,
          TSockCtrl.LookupPort There will be NO dWinSock related events
          during these procedures, any events will be buffered and sent
          after completion.
        . Added sAsyncError to TSockCtrl to handle Async errors similar to
          sError.
        . Changed LookupService to return a 0 instead of an exception when
          service is not found. This is to be consistent with LookupPort.
          Also because Port and Service now automatically fill each other
          the return values of these functions now reflect the same
          information as the properties.
           >> If you have a try except block around a call to LookupService
             you need to check the port for 0 instead.
        . Changed names of the TSockScrl Lookup functions:
          Reverse            LookupHostByAddr
          LookupName         LookupAddrByName
          LookupNameStr      LookupAddrByNameStr
          LookupService      LookupPortByService
          LookupPort         LookupServiceByPort
          >> Time for a global change.
        . Added Async versions of the above Lookup functions it is
          recommended that you use the Async functions to speed up your
          applications processing of winsock messages. Using the non Async
          version will buffer all winsock messages until the information is
          returned. Added: OnAsyncComplete(Sender: Tobject; AsyncInfo:
          TAsyncInfo); TAsyncInfo is the base class for the result. The
          actual AsyncInfo will be on of the following: TAsyncHostInfo,
          TAsyncServiceInfo or TAsyncProtocolInfo; To get the data you ca
          for example Use "if AsyncInfo is TAsyncHostInfo" to determine
          what kind of data was returned, then use (AsyncInfo as
          TAsyncHostInto).Name to retrieve the data. Don't forget to check
          the error and match the TaskHandle with the Taskhandle returned
          from the AsyncLookup* call. All async functions will return ALL
          errors via the OnAsyncComplete mechanism.
        . Fixed FillSocket using wrong port byte order as pointed out by
          Vince Moynihan.
        . Made TSocket.Close virtual at the suggestion of Craig Fransen.
          Created DWSError.pas to go with DWSError.rc and DWSError.res
        . Misc cleanup for 1.4 release.

  V1.3  950420 The Socket Version.
        . Added bitmaps to components, added CloseDown procedure to server,
        . Stopped Server from accepting  >MAXCONN connections.
        . Replaced TClientEvent and TServerEvent with TSocketEvent which passes
          a TSocket reference instead of connection id.
          >> A Change in the parameters replace "cid : integer" with
             "Socket : TSocket".  Delphi will complain of loading of the form
             until you make this change to all of your On* handlers except
             onInfo
          >> This is a big change from the previous versions. Before you needed
              code like "ServerSocket.Client[cid].method" now you can just use
             "Socket.Method".
        . Also changed TClientSocket.Open and TServerSocket.Listen to take
          one more argument which is of type TSocketClass. The creation of
          FConn for TClientSocket and FConns array for TServerSocket is now
          done in the Open and Listen procedures when you know what kind of
          socket you want.
          >> Add TSocket to the parameter list in your calls
        . Moved the common properties (On from Client & Server into TSockCtrl.
        . Numerous changes to make Info notifications work better and added a
          few new ones.
        . Introduced time out handling. Set the TimeOut property of the socket
          classes at design time to set how many seconds it will take before a
          time out is declared. The OnTimeOut event is called when this
          happens.
          >> In the handler you should call Close. Not sure about Server
             handling yet.
        . Replaced TServerSocket.FConns array with a TSocketList
          (derived from TList). Incoming connections are no longer limited by
          MAXCONN. There is a MaxConnections property for limiting incoming
          connections.
        . Added TClientSocket.Options and TServerSocket.ClientOptions
          properties. These determine the mask used for the WSAAsyncSelect
          calls to the corresponding sockets.
        . TSockCtrl now inherits from TComponent. (Yea!, less overhead)
        . TSockets are deleted from server.FConns on close.
        . Correct nl not being set bugs in several methods.
        . Moved LookupName and LookupService from TSocket to TSockCtrl
          >> Remove reference to Conn "ASocket.Conn.LookupName" becomes
             "ASocke.LookupName".
        . Added LookupNameStr to return the address as a string.
        . Moved RecvText and SendText to TSocket's Private section.
          >> Use the Text property.

  V1.2  950410  Added Address property to server.
  V1.1  950407  Corrected TServerSocket bug.
  V1.0  950404  First release.


