![]() |
Sock.pas TSock Component Class Version 1.0 ßeta 2 Written By Tom Bradford © Copyright 1996 By Beach Dog Software ® All Rights Reserved |
Introduction
ßeta Release Notes
Features
Properties
Events
Methods
Support Routines
Examples
As this is a ßeta release of the component, it should be noted that not every aspect of normal operation has been thoroughly tested. Asynchronous client I/O should work perfectly. Blocking communications should work fairly well. Server functionality has been thoroughly tested. Users may want to fool around with Datagram socket functionality because it hasn't been fully tested yet.
- TSock now caches IP addresses in the IPCache global variable. A user shouldn't have to interact with this variable directly. If you need to clear the cache, call the IPCache.Clear method.
- Connected is now determined in two places during normal operation. With a non-blocking socket, Connected is set to TRUE by an FD_CONNECT message and set to FALSE by an FD_CLOSE message. With a blocking socket, Connected is set to TRUE by the socket being opened and set to FALSE by Receive returning 0 content when it performs a WinSock recv.
- TSock allows its Socket property to be assigned. When you assign this property, the component will perform a GetSockOpt to verify that SO_ACCEPTCONN (indicates Listening) doesn't return TRUE. If it does return TRUE, I throw an exception. The socket can't verify that there isn't some other process monitoring the socket, so it will not allow you to assign a listening socket to it.
- The Blocking property has been rewritten so that you can set it even when a connection is present. If set to TRUE, the asynchronous message hook is disabled, and IOCtlSocket is used to turn blocking on. If set to FALSE, the asynchronous message hook is installed. Please note that the TSock events act differently in Blocking and Non-Blocking mode... In asynchronous mode, all events prompt the implementer to perform some action. In blocking mode, with the exception of OnAccept and OnAutoAccept, if an event is triggered at all, it is usually to report some sort of status.
- When dynamically creating a TSock control, it is recommended that you perform an InsertControl to insert the component into an appropriate container. The control requires a Parent to allocate a window handle. If Parent has not been set, the control will use Screen.Forms[0] as a Parent. Window handles are required to perform asynchronous non-blocking socket calls.
- Package caches resolved IP Addresses for faster DNS lookups.
- Supports both TCP and UDP protocols.
- Listening mode will automatically accept incoming connections, create a new TSock component for the connected socket, and spawn a new thread of execution to handle concurrent blocking server connections.
- Support for blocking and non-blocking socket communications.
- Component can transfer blocks of data up to 4 gigabytes in length.
- MIME-standard Base-64 encoding and decoding routines.
- URL encoding and decoding routines.
- Robust state information messaging system for diagnostics and status.
- Support for multiple connections utilizing multiple-threads.
Property Name | Type | Scope | Description |
---|---|---|---|
SocketType | TSocketType | Design | Type of socket. This value can either be stStream or stDatagram. If Listen is set to TRUE, this property will automatically be set to stStream because datagram sockets do not support listening mode. Likewise, if the socket type is set to stDatagram, the Listen property will be set to False (in design mode). |
HostName | String | Design | Host Name or IP Address. The Socket Component will automatically distinguish a Host Name (ex: www.cinteractive.com) from an IP Address (ex: 127.0.0.1). |
PortName | String | Design | Port Number or Service Name. Port Numbers are well known ports such as 80 for HTTP or 7 for Echo. Service Names perform a database lookup into the SERVICES file. |
Blocking | Boolean | Design | Blocking Socket I/O. TRUE causes a socket to block while connecting, waiting for incoming data and writing to the socket. FALSE causes an asynchronous window message to be sent when a connection is made, data is available to be read and written. |
AutoAccept | Boolean | Design | Auto-Accept Incoming Connections. TRUE causes a Listening socket (Listen = TRUE) to automatically accept an incoming connection and call OnAutoAccept as a new thread. If no OnAutoAccept is defined, OnAccept is called. If No OnAccept is defined, the incoming connection will linger. |
Listen | Boolean | Design | Listen For Incoming Connections. If TRUE, creates a thread that loops, listening for incoming sockets and handling them based on the AutoAccept, OnAccept, and OnAutoAccept properties. |
Connected | Boolean | RunTime | Connect Socket Or Check Connection. If set to TRUE, the component attempts to open a socket connection. If set to FALSE, the component closes a current connection. If the value returned is TRUE, the socket is connected, otherwise, it is not. |
Socket | TSocket | RunTime | Returns Socket Value. Returns the value of a connected socket. Returns INVALID_SOCKET (-1) if the socket isn't currently connected. This property also allows the user to set the value of the socket, but this is inadvisable. |
Text | String | RunTime | Sends And Receives Text. If being assigned to, the value being assigned will be sent to the socket. If being read from, any incoming data from the socket will be returned. |
LineBreak | TLineBreak | Design | Sets the method of scanning incoming data for possible line breaks. This property is used in cooperation with the ReceiveLine method for reading an incoming data stream 1 text line at a time. The possible values for this property are lbCR, lbLF, lbCRLF and lbSmart. lbSmart will make guesses as to the form of the incoming data stream based upon content and break the lines accordingly. |
Event Name | Event Description |
---|---|
OnConnect (TObject) |
Occurs when a client socket connects to a remote host. |
OnDisconnect (TObject) |
Occurs when a client socket disconnects from a remote host or when the connection is unexpectedly terminated. |
OnInfo (TObject, TSocketInfo, String) |
Occurs when the component produces a state message. This event sends a TSocketInfo parameter as well as a string with information specific to the task that is being reported on. |
OnRead (TObject, Integer) |
Occurs when data is available to be read from the socket. |
OnWrite (TObject) |
Occurs when the socket will allow data to be written. |
OnAccept (TObject) |
Occurs when a socket is in queue to be accepted. This event can be used in cooperation with the Accept method to perform multi-client server operations. |
OnAutoAccept (TObject, TSock) |
Occurs when AutoAccept is TRUE. Creates a new client socket and invokes OnAutoAccept as a thread separate from the main application. It is the implementer's responsibility to Free the TSock component that is passed. |
Method Name | Method Description |
---|---|
Open : Boolean | Opens a connection to the remote HostName using PortName. Returns TRUE if successful. Returns FALSE if the connection could not be established. |
Close : Boolean | Closes any existing remote connection. |
Send(String) : Boolean | Sends a string to the remote connection. Returns TRUE if successful. |
Receive : String | Returns any incoming data from the socket. Will block while waiting for data if Blocking is set to TRUE and no data is available in the queue. |
SendDatagram(String, String) : Boolean | Sends the text in the first String parameter as a Datagram to the HostName address defined in the second String parameter. Because UDP is by-definition unreliable, this method always returns TRUE. |
ReceiveDatagram(Var String) : String | Returns a string with the Datagram content received from any address through the bound UDP PortName. ReceiveDatagram will set the String parameter to the IP address of the Datagram's originator. |
ReceiveLine : String | Returns the next input line from the input stream for a socket with SocketType set to stStream. This method uses the LineBreak property to determine how to scan the input stream. If the SocketType is set to stDatagram, this method returns the next incoming Datagram in its entirety. Because the entire Input Stream isn't returned by this method, the socket may have already determined that the connection has been closed. In this case, it is the user's responsibility to check for incoming data even if the socket is no longer connected. |
Accept(TSock) : Boolean | Accepts the next available incoming socket from the listening loop. Accept return TRUE if successful. This method also assigned the TSock parameter to a valid TSock connection component. It is the implementer's responsibility to Free this component when it is no longer needed. Also, the new component is created with no Event handlers, so the implementer is responsible for assigning them if the socket is non-blocking. This event will only be triggered if Listen is TRUE. |
HostLookup(String) : TInAddr | Looks up a remote host using the String parameter. The parameter can either be an IP address (ex: 111.111.111.111) or a domain name (ex: www.cinteractive.com). The value that is returned is a TInAddr structure that can be used when building a TSockAddrIn for binding a socket to an address. |
PortLookup(String) : Word | Looks up a service port using the String parameter. The parameter can either be a textual service name (ex: echo or Finger) or a port number (ex: 80). The value that is returned is a unsigned short in network byte order. |
StartListen : Boolean | Sets the socket component into listening mode. The result is TRUE if successful and FALSE otherwise. This method is the same as setting Listen=TRUE and then checking the value of Listen. |
StopListen : Boolean | Turns listening mode off. |
Routine Name | Routine Description |
---|---|
WSDescription : String | Returns a vendor-defined string that describes the presently running WinSock implementation. This information is obtained while performing an initial WSAStartup WinSock call. |
WSASystemStatus : String | Returns a vendor-defined string containing system status. |
SocketInfoText(TSocketInfo) : String | Given the TSocketInfo parameter, returns a string that describes the parameter. This function can be used in conjunction with an OnInfo event. |
ErrToStr(Integer) : String | Given the Integer parameter, returns the WinSock defined string associated with a particular error code. TSock uses this support routine internally for translating asynchronous errors to TSockException exceptions. |
Base64Encode(String) : String | Converts the String parameter to a MIME-standard Base-64 encoded block and returns the conversion as the String result. |
Base64Decode(String) : String | Converts the String parameter from a MIME-standard Base-64 encoded block and returns the conversion as the String result. |
URLEncode(String) : String | Converts the String parameter to a URLEncoding scheme and returns the conversion as the String result. |
URLDecode(String) : String | Converts the String parameter from a URLEncoding scheme and returns the conversion as the String result. |
There are a few sample applications and more on the way:
- SockTest is a general purpose socket testing client. It demonstrates the non-blocking application of the TSock component. It allows a user to open any port on any host, send any data, and watch what comes back.
- SrvTest is an implementation of the Echo protocol. This protocol is simple. Once the server answers, it spits back whatever the client sends to it. This application demonstrates how to write a multi-threaded blocking server.
- Test64 is a general-purpose Base-64 and URL encoding and decoding tester.
- Proxy is a simple HTTP proxy server. It demonstrates how to write a multi-threaded blocking server as well as how to dynamically create TSock objects and connect them to a remote port. The proxy server itself does not perform content caching but it serves as a good starting point for a custom implementation.