* intentionally removed DOC header/footer so that hbdoc/hbdoc2 ignore this file
* please see en-EN/hbinet.txt which now replaces this file
* harbour/examples/hbdoc2/hbdoc2.prg
* removed 'merge' lines mistakenly left in
348 lines
19 KiB
Plaintext
348 lines
19 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
HARBOUR INET API
|
|
------------------
|
|
|
|
|
|
Giancarlo Niccolai <gian@niccolai.ws>
|
|
|
|
intentially removed DOC header/footer so that hbdoc/hbdoc2 ignore this file
|
|
|
|
please see en-EN/hbinet.txt which now replaces this file
|
|
|
|
* $TEMPLATE$
|
|
* Document
|
|
* $NAME$
|
|
* Harbour Inet functions
|
|
* $CATEGORY$
|
|
* Document
|
|
* $ONELINER$
|
|
* HARBOUR INET API
|
|
* $DESCRIPTION$
|
|
*
|
|
* STATUS OF THIS DOCUMENT
|
|
*
|
|
* This is just a draft, a survival guide with minimal API instructions
|
|
* extracted from the inet.c program comments and from some posting to
|
|
* the xharbour newsgroup.
|
|
*
|
|
* More adequate version will be available soon.
|
|
*
|
|
*
|
|
* HARBOUR INET API
|
|
* ================
|
|
*
|
|
* Startup / cleanup functions
|
|
* ---------------------------
|
|
*
|
|
* hb_InetInit() -->NIL
|
|
* Activates inet support; mainly used for winsock start up at the moment, but
|
|
* could be used in the future for many other purpose. Put it at the beginning
|
|
* of every program using INET functions.
|
|
*
|
|
* hb_InetCleanup() -->NIL
|
|
* Closes Inet support; mainly used for Windows. Put it at the end of any program
|
|
* using Inet functions, just before the program exits.
|
|
*
|
|
* hb_InetCreate() --> SOCKET
|
|
* Creates the raw data of the socket, that can be passed to an asynchronous
|
|
* connection function (hb_InetConnect or hb_InetConnectIP). This will prevent the
|
|
* connection function from allocating some data that could be never used in
|
|
* certain cases, i.e. an asynchronously detected timeout.
|
|
*
|
|
* hb_InetClose( SOCKET ) --> NUMERIC
|
|
* Closes the socket, notifiying both ends of the communication pipe that the
|
|
* connection is over. If you have threads waiting for data to be read from
|
|
* this socket, this method will make them stop waiting and return an error
|
|
* (socket closed) to their callers.
|
|
* The method does not destroy the socket, which can be used by subordinate
|
|
* threads to check that the socket is closed, and so they should stop as soon
|
|
* as they can. Don't destroy the socket unless you are sure that no other
|
|
* thread is using it.
|
|
* RETURNS 0 on success or -1 on error; on error, the error code is set;
|
|
* (actually, on success the socket error code is set to 1 -- socket closed )
|
|
*
|
|
* hb_InetDestroy( SOCKET ) --> Numeric
|
|
* Closes AND destroys a socket. After this call, the socket can't be used
|
|
* anymore. Returns 0 on success -1 on failure.
|
|
*
|
|
* hb_InetSetTimeout( SOCKET, nMillisecs ) --> NIL
|
|
* Sets the default timeout of the given socket. Default timeout is used in all
|
|
* blocking operations: if the operation can't be done in nMillisec milliseconds,
|
|
* the function returns immediately and the hb_InetErrorCode( SOCKET ) returns -1.
|
|
* The default timeout is not the maximum time that a function using the socket
|
|
* is allowed to execute: it is the maximum time that each single blocking
|
|
* operation inside that function is allowed to hold the control of the socket.
|
|
* So, an function like hb_InetReadAll(), that may repeat a raw recv() several
|
|
* times, is not guaranteed to terminate in nMillisecs, but you are guaranteed
|
|
* that if any of that raw socket read operation is going to take more than
|
|
* nMillisecs, the function will be terminated.
|
|
* When created, a socket is created with an infinite default timeout (-1).
|
|
*
|
|
* hb_InetGetTimeout( SOCKET ) --> NUMERIC
|
|
* Returns the timeout set for the given socket.
|
|
*
|
|
* hb_InetClearTimeout( SOCKET, nMillisecs ) --> NIL
|
|
* Clears the default timeout of the given socket. Default timeout is used in all
|
|
* blocking operations.
|
|
*
|
|
* Informative functions
|
|
* ---------------------
|
|
*
|
|
* hb_InetErrorCode( SOCKET ) --> Numeric
|
|
* Returns the last error code that has been provoked by a network operation,
|
|
* or 0 if none. Error codes are the ones used for winsock or UnixSockets (they
|
|
* are the same); 1 is reserved for "connection closed" message.
|
|
*
|
|
*
|
|
* hb_InetErrorDesc( SOCKET ) --> String
|
|
* Returns a string describing the last error that occurred in the socket;
|
|
* the string is system dependent, and should be used only for debugging
|
|
* purposes.
|
|
*
|
|
*
|
|
* hb_InetCount( SOCKET ) --> Numeric
|
|
* Returns the amount of characters read or written in the latest socket
|
|
* operation.
|
|
*
|
|
* hb_InetAddress( SOCKET ) --> STRING
|
|
* Returns a string representing the remote server address in quad dot notation,
|
|
* e.g. "192.168.1.1", or the local server address if the socket is server
|
|
* side.
|
|
* TODO: have a version that returns a vector of 4 numbers.
|
|
*
|
|
* hb_InetPort( SOCKET ) --> STRING
|
|
* Returns the port to which this socket is bound, or the remote port if this
|
|
* socket is connected with a remote host or client
|
|
*
|
|
* Server Side socket functions
|
|
* ----------------------------
|
|
*
|
|
* hb_InetServer( port [, cBindAddr [, nListenLimit]] ) --> SOCKET
|
|
* Creates a server that can accept connections from client on a certain port.
|
|
* If the computer on which hb_InetServe is called has more than one logical
|
|
* interface (e.g. one network card, one loopback and one PPP address),
|
|
* cBindAddr can be specified to select only one of these interfaces to accept
|
|
* connections for this process. This is useful when a server is present on
|
|
* two networks, and the service is to be available only in one of them. Also,
|
|
* the same port on other addresses is left free to be used, so you can have
|
|
* different server programs running for different networks but managing
|
|
* the same service. In example, an FTP server available to the internal
|
|
* network could be radically different from an FTP server available for
|
|
* the internet.
|
|
* nListenLimit is an internal parameter and rarely needs to be specified.
|
|
* This is the number of incoming connections accepted by kernel before the
|
|
* kernel has the chance to report them to the application program. If
|
|
* the sockets receive nListenLimit connections before accepting them
|
|
* all, the nListenLimit + 1 connection will be notified to be "busy" by
|
|
* the kernel. Usually, a value of 10 (the default) is enough for even
|
|
* a heavy duty server.
|
|
* On error, sets error description in the newly returned socket.
|
|
*
|
|
* hb_InetAccept( SOCKET ) --> SOCKET
|
|
* Waits until a connection is available on a socket created with hb_InetServer;
|
|
* Returns a socket that can be used to communicate with the incoming client.
|
|
* On error, NIL is returned and error code sets in the passed SOCKET.
|
|
* This error can be accessed using hb_InetErrorCode() function.
|
|
*
|
|
* Client side socket functions
|
|
* ----------------------------
|
|
*
|
|
* hb_InetConnect( cAddress, nPort ) --> SOCKET
|
|
* hb_InetConnect( cAddress, nPort, SOCKET ) --> NIL
|
|
* Connects to a remote server described by cAddress, that can be in
|
|
* quad dot notation (e.g. "192.168.1.1") or in DNS name (e.g.
|
|
* "www.xharbour.org"), using the desired port.
|
|
* hb_InetConnect uses "gethostbyname" C system call to
|
|
* find the network address of the specified server; this means that
|
|
* this call is an hybrid function doing both a DNS scan and a TCP/IP
|
|
* connection. hb_InetConnect is not thread safe, and the xHarbour
|
|
* program must take care that two hb_InetConnect functions are never
|
|
* called at the same moment from two different threads (or that
|
|
* hb_InetGetHosts is not called in the same moment as an hb_InetConnect).
|
|
* The second version of this function accepts a pre-built socket
|
|
* as a parameter. This allows to kill asyncronously a thread waiting
|
|
* for hb_InetConnect to connect, and then cleaning up the leftover
|
|
* socket data. Also, it is possible to give timeout to the given SOCKET,
|
|
* but this timeout will be used only in the connection phase, after that
|
|
* the network address resolution is completed. Use GetHosts() and
|
|
* hb_InetConnectIP for a finer timeout control.
|
|
* On error, the error of the returned socket is set. The error could
|
|
* be due to unavailable name resolving service, host name not valid,
|
|
* host address not reachable and host reachable but port not open.
|
|
*
|
|
* hb_InetConnectIP( cAddress, PORT ) --> SOCKET
|
|
* hb_InetConnectIP( cAddress, PORT, SOCKET ) --> NIL
|
|
* Connects to a remote server described by cAddress, that can be specified
|
|
* only in quad dot IPV4 notation (e.g. "127.0.0.1"), using the desired port.
|
|
* This version of hb_InetConnect does not use gethostbyname, and thus is thread
|
|
* safe and can be used in combination with hb_InetGetHosts to have a finer
|
|
* timeout control while connecting to a server, and a finer error control.
|
|
* The second version of this function accepts a pre-built socket
|
|
* as a parameter. This allows to kill asyncronously a thread waiting
|
|
* for hb_InetConnectIP to connect, and then cleaning up the leftover
|
|
* socket data. Also, it is possible to give timeout at the given SOCKET.
|
|
*
|
|
* On error, the error of the returned socket is set.
|
|
*
|
|
* Sending and receiving data
|
|
* ----------------------------
|
|
*
|
|
* hb_InetRecv( SOCKET, @cString [, nAmount] ) --> NUMERIC
|
|
* Reads at maximum nAmount bytes (or a number of bytes equal to cString
|
|
* length if nAmount is not given) from the socket into cString.
|
|
* The parameter cString must be preallocated so that it has enough
|
|
* space to receive the data. The routine will block the thread until some
|
|
* bytes are read from the socket, the socket is closed (either from the
|
|
* receiver or the sender side) or a network error occurs, whichever comes
|
|
* first. In the latter cases, an error is set, and only the characters
|
|
* received until premature end of communications are returned.
|
|
* Notice that there is no guarantee that all the available bytes will be
|
|
* read before the function returns, in fact, hb_InetRecv returns as soon it
|
|
* is able to fill cString with one or more bytes. To block the current
|
|
* process until the whole cString is filled (or nAmount bytes are read),
|
|
* use the hb_InetRecvALL().
|
|
* RETURNS the number of the characters read from the SOCKET.
|
|
*
|
|
* hb_InetRecvAll( SOCKET, @cString [, @nAmount] ) --> NUMERIC
|
|
* This function works exactly as hb_InetRecv, except for the fact that it
|
|
* blocks until nAmount bytes are read, if nAmount is given, or
|
|
* cString is filled for its whole length.
|
|
* RETURNS the number of the characters read from the SOCKET. Might be
|
|
* less than nAmount on premature socket closing or on network error.
|
|
*
|
|
* hb_InetRecvLine( SOCKET [, @nResult, [, nMaxLength [, nBufSize]]] ) --> STRING
|
|
* Blocks the calling thread until a sequence CRLF is read from the socket.
|
|
* Incremental allocation and end-of-line checking are done in an efficient
|
|
* way. If an error occurs, or if the stream is closed before a CRLF is read,
|
|
* the function returns nothing and sets the socket error.
|
|
* The returned string does not contain the trailing CRLF sequence, so an
|
|
* empty line is effectively returned as an empty string.
|
|
* If the nResult parameter is given, it will contain the number of bytes
|
|
* read from the socket, including the CRLF sequence, so that in normal
|
|
* conditions, nResult will report a count equal to the length of the
|
|
* returned string plus 2. nResult will be 0 if stream is closed before
|
|
* a CRLF sequence is read, and will be -1 on error.
|
|
* An optional MaxLength parameter can be given to allow a maximum character
|
|
* count before the data is returned anyway. If this number is hit before
|
|
* a CRLF sequence is encountered, nResult will contain the value one.
|
|
* Finally, a nBufSize parameter can be given. If not, memory allocation
|
|
* will be increased by discrete amounts of 80 bytes. The programmer
|
|
* can provide here a different allocation strategy (e.g. setting nBufSize
|
|
* equal to nMaxLength, memory for reading the line will be allocated only
|
|
* once, at the beginning of the function).
|
|
*
|
|
* hb_InetRecvEndBlock( SOCKET [, cBlock [, @nResult, [, nMaxLength [,
|
|
* nBufSize]]]] ) --> STRING
|
|
* This function operates exactly the same way as hb_InetRecvLine, but
|
|
* the "record termination" is customizable thorugh the cBlock parameter.
|
|
* If not given, this parameter defaults to the CRLF sequence.
|
|
* Provided by: Marcelo Lombardo
|
|
*
|
|
* hb_InetDataReady( SOCKET [, nMillisecs] ) --> NUMERIC
|
|
* Verifies if some data is available to be read in the socket without blocking
|
|
* execution of the caller. If nMillisecs is not given, the function returns
|
|
* immediately 1 if there is some data to be read, 0 if there isn't any data and
|
|
* -1 in case of error. If nMillisecs is given, the functon will wait up to that
|
|
* amount of milliseconds for data to be available; if some data arrives in the
|
|
* meanwhile, the wait is immediately interrupted.
|
|
* The next hb_InetRecv() function will read all the available data (up to the
|
|
* required length) without blocking.
|
|
* On error, hb_InetErrorCode and hb_InetErrorDesc can be use to determine what kind
|
|
* of error happened.
|
|
*
|
|
* hb_InetSend( SOCKET, STRING [, nLength ] ) --> NUMERIC
|
|
* Send data being stored in a string over the socket. Returns the amount of
|
|
* data written, 0 if the socket has been closed in the meanwhile or -1 on
|
|
* error. The nLength parameter can be given to allow writing only a part of
|
|
* the string.
|
|
* Please, notice that there is no guarantee that all your string will be
|
|
* sent, as this is a decision that is up to the OS; this function does not
|
|
* take care to ensure that the data is really sent; so you should check for
|
|
* the returned number, and send the part that has not been sent.
|
|
* To ensure that all the data is sent before the function returns, use the
|
|
* hb_InetSendAll() function.
|
|
* On error, the error in the socket is set.
|
|
*
|
|
* hb_InetSendAll( SOCKET, STRING [, nLength ] ) --> NUMERIC
|
|
* This function works exactly as hb_InetSend() but it ensures that all the
|
|
* data to be sent is written before returning.
|
|
*
|
|
* Utility Functions
|
|
* ------------------
|
|
*
|
|
* hb_InetGetHosts( cName ) --> aHosts
|
|
* Returns an array containing all the IP addresses associated with a given
|
|
* host name. The IP addressess returned by this funtion are strings in
|
|
* quad dot notations, eg "192.168.1.1", and can be directly used into
|
|
* hb_InetConnectIP(). cName can be any string: valid DNS names (eg.
|
|
* "www.myserver.com"), locally available names (e.g. "localhost" or
|
|
* windows Network Neighborhood names), or even IP addresses in quad
|
|
* dot notation.
|
|
* NOTE: This function is not thread safe (by design), and programmers
|
|
* must be sure not to use it at the same time in two different threads,
|
|
* or not to use it together with a hb_InetConnect(). If this kind of situation
|
|
* should ever arise, you are advised to use a thread MUTEX.
|
|
* On error, and if the server can't be found, the function returns NIL.
|
|
*
|
|
* hb_InetGetAlias( cName ) --> aHosts
|
|
* Returns an array containing the aliases ( CNAME DNS records ) by
|
|
* which the server is currently known. Whether this function is able
|
|
* to have the complete list of aliases or not depends on the verbosity
|
|
* of the DNS server.
|
|
*
|
|
* hb_InetCRLF() --> String
|
|
* Returns a CRLF sequence used in many internet protocols.
|
|
*
|
|
* UDP (User Datagram Protocol) Compliant Routines
|
|
* -----------------------------------------------
|
|
*
|
|
* hb_InetDGram( [bBroadcast] ) --> SOCKET
|
|
* Creates a datagram oriented socket that will be able to send data and
|
|
* eventually receive data. Since the socket is not bound, the program can't
|
|
* retrieve the address at which this socket appaers to be, but a second
|
|
* socket receiving a message sent from this one would be able to reply
|
|
* correctly with a datagram that can be read from a non-bound socket.
|
|
* If bBroadcast is set to .T., the routine creates a broadcast capable socket:
|
|
* it will be able to receive and send broadcast messages. On most systems this
|
|
* requires special user privileges.
|
|
* Returns the socket, and if an error occurs, the socket error message
|
|
* and code are set.
|
|
*
|
|
* hb_InetDGramBind( nPort, [cAddress [, bBroadcast] ] ) --> SOCKET
|
|
* Creates a datagram oriented socket and binds it to a particular port, and
|
|
* eventually to a certain interface if cAddress is given and not NIL.
|
|
* If bBroadcast is set to .T., the routine creates a broadcast capable socket:
|
|
* it will be able to receive and send broadcast messages. On most systems this
|
|
* requires special user privileges.
|
|
* Returns the socket, and if an error occurs, the socket error message
|
|
* and code are set.
|
|
*
|
|
* hb_InetDGramSend( SOCKET, cAddress, nPort, cBuffer [, nSize ] ) --> NUMERIC
|
|
* Sends a datagram (a fixed length data) to a determined ip address (cAddress,
|
|
* to be specified in quad-dot notation) and port. If nSize is not specified,
|
|
* all the data in cBuffer will be sent; if nSize is specified, only
|
|
* the first nSize bytes of cBuffer will be sent.
|
|
* There isn't any guarantee that all the data required to be written is
|
|
* really sent to the socket: the calling program should check for the
|
|
* numeric return and send iteratively the unsent data to complete
|
|
* the message.
|
|
* Anyway, the raw datagram is sent and received as once, and any data
|
|
* less than the system datagram size will be sent and received
|
|
* as a single item.
|
|
* If the socket is created in broadcast mode, the cAddress element
|
|
* can be a broadcast address.
|
|
* Returns -1 on error, or the number of bytes actually sent on success.
|
|
*
|
|
* hb_InetDGramRecv( SOCKET, cBuffer [, nSize ] ) --> NUMERIC
|
|
* Reads at maximum nSize bytes incoming from a UDP socket, if nSize is
|
|
* given, or reads at maximum cBuffer length if nSize is not given.
|
|
* There isn't any guarantee that all the data required to be read is
|
|
* really sent from the kernel to the application: the kernel should
|
|
* just return the last complete datagram that has been received, up
|
|
* to nSize bytes.
|
|
* Returns -1 on error, or the number of bytes actually read on success.
|
|
*/
|