/* * $Id$ */ HARBOUR INET API ------------------ Giancarlo Niccolai 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. */