Copyright: Sockets Online Help, Beta Version 1.00.70


Windows Sockets for Windows NT

Windows NT fully supports the Windows Sockets functions as defined in the Windows NT SDK (Software Development Kit). However, Windows NT has some additional features available through its Windows Sockets interface that are not described in the Windows Sockets specification. This document describes the extended features of the Windows Sockets interface in Windows NT, a superset of the Windows Sockets functionality.

Some of the features described in this document were not implemented in the initial release of Windows NT but are available in the beta release of Windows NT version 3.5. The most notable new features are the SO_SNDTIMEO, SO_RCVTIMEO, and SO_OPENTYPE socket options and support for NetBIOS providers.


Support for 32-bit Applications

Included with the Windows NT release disks is the WINSOCK.DLL file, which provides the APIs necessary for 16-bit applications to use Windows Sockets through 16-bit subsystem of Windows NT. Win32 applications use a different DLL, WSOCK32.DLL, which exports routines that take exclusively 32-bit arguments.

The 32-bit versions of the Windows Sockets APIs take all the same parameters, with the notable exception that all int and SOCKET parameters are widened from 16 bits to 32 bits. This widening is of no concern if you are writing applications to be portable between 16-bit and 32-bit environments, since the compiler performs the necessary steps automatically.


Windows NT Socket Handles

From a developer's standpoint, perhaps the most notable aspect of the Windows Sockets support in Windows NT is that the handles returned from the socket and accept functions are native Windows NT system handles that have been opened, by default, as "asynchronous" or "overlapped" handles. This allows an application to use the handles as arguments to system routines in addition to the Windows Sockets routines and also to share the handles between threads and processes.


Sharing Sockets Between Threads

Because a handle value is global to all threads in a process, a handle can be accessed in any thread, even threads that did not open the handle. For example, one thread can call the socket function, which returns a socket handle. A different thread in the same process can make other Windows Sockets calls with the returned socket handle. No special action is required to enable the second thread to use the handle; it just needs to obtain the handle value.

It is also possible for multiple threads to access a single socket simultaneously, but an application that does this must synchronize important actions. For example, if one thread does a bind on a socket at the same time another thread is doing a getsockname, then because of the preemptive scheduling of Windows NT there are no guarantees that the getsockname will execute before the bind. It could happen that the getsockname returns WSAEINVAL because the socket is not yet bound.

Another important example of simultaneous access in multiple threads to a single socket is data transfer. An application can have one thread calling send on a socket and another thread calling recv with no adverse effects whatsoever. However, if multiple threads do a send on a socket, then there are no guarantees as to the order of data delivery. The only guarantee is that the data in each send will be sent as a contiguous chunk — there is no possibility of intermixing data from different send calls. The analagous situation exists for multiple simultaneous recv calls — there is no guarantee as to which will finish first, but the data returned to any given recv is contiguous.

Making multiple simultaneous calls from different threads will not in any way damage the internal state of the socket maintained by Windows Sockets. Windows Sockets internally synchronizes the socket state whenever it changes in any way. Therefore, you need not worry about synchronizing calls for the sake of preserving the internal state of Windows Sockets.


Sharing Sockets Between Processes

Handles in Windows NT can also be shared between processes. However, since each process has its own handle table, it is more work to share handles between processes than between threads. There are two mechanisms for sharing handles between processes: inheritance and duplication.

In inheritance, a process (called the "parent process") creates another process (called the "child process") using the Win32 function CreateProcess with the fInheritHandles parameter set to TRUE. This causes the system to map into the child's process table all the inheritable handles of the parent process. Note that while not all Win32 handles are inheritable (inheritance requires opening a handle in a special manner), all socket handles are inheritable.

Once you create the child process, it must be given the values of the handles it needs to access. When it has the handle values, it can pass the handles to Windows Sockets or other APIs.

In duplication, a process can pass a handle to another existing process with the Win32 function DuplicateHandle. This function allows one process to map a handle into the process table of another process, although the specific handle value may be different in the receiving process. For more information on duplicating and inheriting handles, see the Win32 API documentation.

When sharing sockets between processes, the same synchronization issues exist as when sharing sockets between threads. In addition, you must be aware of two other special properties of sharing sockets between processes.

First, since both processes have a view of the socket handle, both processes must call closesocket before the system closes the socket. The process that first calls closesocket only takes the socket out of its internal handle table. The first closesocket call does not affect the second process's access to the socket in any way. The second closesocket does the actual cleanup of the socket, including initiating the protocol-level virtual circuit termination if the socket is connected. If the socket sharing is really a "hand-off" from one process to another, it is best to close the socket in the first process immediately after the CreateProcess or DuplicateHandle call.

Second, some socket options, such as SO_LINGER, are kept on a per-process basis. Therefore, after a socket handle has been passed to a second process, changes in socket options by one process may not be reflected in the other process. For this reason it is advisable to set up any socket options that both processes will need before sharing the socket handle.

Many Unix services that use sockets make use of child process creation and inheritance to handle multiple simultaneous clients. This is typically done by a "master" process creating a socket, calling listen on the socket, and using accept to accept incoming connections. Then this process creates a "slave" process that actually services the client while the master immediately closes the accepted socket. This is useful in Unix, where multiple threads are generally not available, and this algorithm will work in Windows NT. However, processes use more memory than threads. Context switches between processes use about twice the CPU instructions used in context switches between threads within a single process. In addition, threads can share information much more easily than processes, so it is usually easier in the long run to use threads rather than processes. For all these reasons, it is strongly recommended that you write a service that handles multiple clients simultaneously so that it uses one thread per client rather than one process per client. It is even better to use multiple clients per thread. This technique is discussed in "Accessing Sockets Through the Win32 I/O APIs," following.


Using Sockets as Standard I/O Handles

A special case of sharing sockets between processes is using sockets as standard input, output, or errors for a child process created with CreateProcess. This is useful for causing a process to unwittingly read input from a socket and to write output to a socket. Such a child process may "know" absolutely nothing about sockets or even networks; it just reads from its standard input and writes to its standard output.

There are two key steps in making this possible. First, a socket must be opened for "synchronous" access (that is, not overlapped) with the SO_OPENTYPE socket option described following. Second, the socket must be connected with either the connect or accept Windows Sockets API calls. After these steps, making a socket handle accessible as a standard I/O handle is just like doing so for other handles: Specify the handle value in the hStdInput, hStdOutput, and/or hStdError fields of the STARTUPINFO structure passed to CreateProcess Win32 API. The created process will read from and write to the socket without ever knowing it is a socket.


Accessing Sockets Through the Win32 I/O APIs

Since Windows NT socket handles are system socket handles, it is possible to use Windows NT socket handles as parameters to several of the Win32 APIs. The most useful Win32 APIs for sockets are the ReadFile and WriteFile functions since these allow an application to perform aynchronous I/O on a handle by means of the lpOverlapped parameter. In overlapped I/O, the request is started with the initial call but the call does not block waiting for the request to be completed. For example, if an application makes an overlapped ReadFile call when no data exists to be read on a socket, the calling thread will regain control immediately rather than waiting for data to arrive on the socket. The application will be notified when the request has been completed via the lpOverlapped parameter.

Overlapped I/O differs from the socket concept of nonblocking I/O in that overlapped I/O actually performs the I/O eventually if it cannot be completed immediately. In nonblocking I/O, if the I/O cannot be performed immediately, then it fails with the error code WSAEWOULDBLOCK and the application must reissue the request at a later point.

Overlapped I/O is especially useful in a service that handles multiple sockets. A single thread can be used to perform I/O on all of the sockets without the overhead of the select call. Also, the use of overlapped I/O allows an application to mix different types of I/O in a single thread; for example, I/O on named pipes and I/O on sockets.

Because Windows NT socket handles are, by default, opened as overlapped handles, an application must specify the lpOverlapped parameter on calls to ReadFile and WriteFile. However, an application can also use the SO_OPENTYPE socket option to open sockets that are not overlapped.


Accessing Sockets Through the C Run-time Libraries

The C run-time libraries (CRTs) provide useful functionality for input and output formatting through routines such as fprintf, fscanf, and so on. It may also be useful to access socket handles through these routines in existing code that uses C run-time calls such as _read and _write.

The C run-time libraries take two different inputs to identify a file: a CRT handle (different from a system handle such as a socket) and a file pointer. The low-level I/O routines, such as _read, take CRT handles, while the more sophisticated formatting routines, such as fprintf, take file pointers.

To access sockets through the C run-time routines, an application must perform several steps:

1.	Use the SO_OPENTYPE socket option described following so that any opened socket handles are synchronous.

2.	Open a connected socket by calling either socket and connect or by calling accept. It is legal to use datagram sockets, although their inherent unreliability may make them unsuitable for C run-time access in many applications.

3.	Obtain a CRT socket handle with the _open_osf_handle C run-time API. If the application intends to use only the low-level C run-time calls, the handle returned by this call is sufficient and the application is ready to make C run-time calls.

4.	If the application wants to use the higher-level C run-time calls that do data formatting, the application must obtain a file pointer (FILE *) by using the _fdopen C run-time call.


Socket Options Specific to Windows NT

Windows NT supplies several socket options beyond those included in the Windows Sockets specification. Because these options are not currently part of the formal Windows Sockets specification, an application that uses these options is not compatible with Windows Sockets. However, for applications written exclusively for Windows NT, these options can be very useful.


SO_SNDTIMEO and SO_RCVTIMEO

These two options set up timeouts for the send, sendto, recv, and recvfrom functions. You can obtain the same functionality by calling select with a timeout just before the I/O call, but these options offer a significant improvement in performance by avoiding a kernel transition and the other overhead of the select call. For any code whose performance is very critical, applications should use these timeout options rather than select.

You can set these options on any type of socket in any state. The default value for these options is zero, which refers to an infinite timeout. Any other setting is the timeout, in milliseconds. It is legal to set the timeout to any value, but values less than 500 milliseconds (half a second) are interpreted to be 500 milliseconds.

To set a send timeout, use

int timeout = TIMEOUT_VALUE;

int err;

SOCKET s;

s = socket( ... );

err = setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout) );

if ( err != NO_ERROR ) {

    /* failed for some reason... */

}

where TIMEOUT_VALUE is the needed timeout in milliseconds. To set a receive timeout, substitute SO_RCVTIMEO for SO_SNDTIMEO in the preceding example.

After setting one of these options to a nonzero value, I/O through the Windows Sockets calls fails with the error WSAETIMEDOUT if the request cannot be satisfied within the specified timeout. If a request times out, an application has no guarantees as to how much data was actually sent or received in the I/O call.


SO_OPENTYPE

By default, all socket handles are opened as overlapped handles so that asynchronous I/O can be performed on them. However, in many situations it is preferable to have nonoverlapped (synchronous) socket handles. For example, only nonoverlapped handles can be used with the C run-time libraries or used as standard I/O handles for a process. The SO_OPENTYPE socket option allows an application to open non-overlapped socket handles.

The SO_OPENTYPE option must be set on a per-thread basis since it affects how each thread opens sockets, and it must be set before a socket handle is opened in order to affect the socket. The default value for this option is zero, which opens sockets as overlapped handles. Other possible values for this option are SO_SYNCHRONOUS_ALERT and SO_SYNCHRONOUS_NONALERT. SO_SYNCHRONOUS_ALERT allows operations performed on the socket handle to be alerted by an APC routine (software interrupt), while SO_SYNCHRONOUS_NONALERT blocks APCs from being delivered to threads waiting on requests on socket handles. For more information on APCs, see the Win32 Programmer's Reference. Typically, it does not matter which of these options is chosen: either makes socket handles nonoverlapped.

Use the following to open a nonoverlapped socket handle:

SOCKET s;

int optionValue = SO_SYNCHRONOUS_NONALERT;

int err;

err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue) );

if ( err != NO_ERROR ) {

    /* failed for some reason... */

}

s = socket( ... );

Note that the socket handle passed in to setsockopt is ignored for this option.

The SO_OPENTYPE socket option affects both the socket and accept Windows Sockets calls. The setting of SO_OPENTYPE is preserved throughout the lifetime of the thread in which it is set, so it is not necessary to set its value before each socket opens. However, it is necessary to set this option for every thread that opens sockets if the nondefault behavior is desired. Also, if different layers of an application open sockets and have different expectations of the type of handles opened, it is advisable to use getsockopt before the setsockopt call to obtain the original setting of SO_OPENTYPE, then reset SO_OPENTYPE to the original value after opening the socket. For example,

SOCKET s;

int originalValue;

int optionValue = SO_SYNCHRONOUS_ALERT;

int err;

int optionLength = sizeof(originalValue);

/* Get the original setting of SO_OPENTYPE. */

err = getsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&originalValue, optionLength );

if ( err != NO_ERROR ) {

    /* failed for some reason... */

}

/* Set SO_OPENTYPE so that we get a synchronous socket handle. */

err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue) );

if ( err != NO_ERROR ) {

    /* failed for some reason... */

}

s = socket( ... );

/* Reset the SO_OPENTYPE setting to its original value. */

err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue) );

if ( err != NO_ERROR ) {

    /* failed for some reason... */

}

This technique is especially useful in DLLs that use synchronous sockets.

There are some Windows Sockets features that you cannot use with synchronous sockets. The WSAAsyncSelect call cannot be used with synchronous sockets and will fail with the error WSAEINVAL. It is also not possible to set the SO_SNDTIMEO and SO_RCVTIMEO socket options on synchronous sockets; setsockopt with these options on synchronous sockets fails with WSAEINVAL as well.


Multiple Protocol Support

In addition to TCP/IP, Windows NT supports several additional transport protocols through its Windows Sockets interface. Although these protocols are not explicitly addressed in the Windows Sockets specification, the interface to Windows Sockets over different transport protocols is quite feasible. This is because the fundamental job of a transport protocol is data transfer, along with the fact that Windows Sockets provides a rich interface for low-level data transfer in applications. Having a common, well-known API interface allows applications to be ported quickly between different transport protocols, and there are several successful examples of this.

Because of the architecture of the Windows Sockets component of Windows NT, all supported transport protocols are accessed through the same DLL, WSOCK32.DLL. In fact, a single application can simultaneously use sockets of different transport protocols.

An application uses the parameters to the socket function to specify the protocol it will use. For example, a TCP socket is opened with

s_tcp = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

while an SPX socket is opened with

s_spx = socket( AF_IPX, SOCK_SEQPACKET, NSPROTO_SPX );

After opening a socket for a specific protocol, all actions performed on the socket go through the specified protocol. In the preceding example, if the application did a listen on the s_tcp socket but not on the s_spx socket, it would receive incoming connects through TCP but not receive incoming connects through SPX.


Protocol Characteristics

It is important to understand the different characteristics of transport protocols when designing an application that uses them. While all transport protocols share the same fundamental purpose of bidirectional data transfer, many details of the data transfer differ. The following sections list key characteristics of transport protocols that apply to Windows Sockets applications.


Addressing

The most obvious difference between different transport protocols is the way each uses transport addresses, called "sockaddrs" in Windows Sockets terms. Virtually all transport protocols expose different address formats to applications, the one exception being NetBIOS protocols, which all use the same address format.

A number of Windows Sockets APIs take sockaddrs as input or output parameters, including bind, accept, sendto, recvfrom, getsockname, and getpeername. For all these functions a sockaddr is really two arguments: a pointer to the sockaddr structure itself and a length integer that gives the number of bytes in the sockaddr. For many transport protocols the length of a sockaddr is always the same, but sockaddr lengths can differ between transport protocols. For example, a TCP/IP sockaddr has 16 bytes and an IPX/SPX sockaddr has 14 bytes.

The format of sockaddr structures used by a transport protocol is specified in the af, or "address family" argument to the socket function. All TCP/IP sockets (including both TCP and UDP sockets) are opened with the AF_INET address family, while IPX/SPX sockets are opened with AF_IPX. Other transport protocols use different address family values as defined in the header file WINSOCK.H.

An application must fill in a sockaddr when binding to a local address or connecting to a remote address, and also to interpret the sockaddrs returned from the accept, sendto, recvfrom, getpeername, and getsockname functions.


Connection-Oriented vs. Connectionless Transport

In a connection-oriented transport protocol, applications are required to establish a virtual circuit (sometimes abbreviated to "VC") before data transfer can take place. Virtual circuit establishment is assymetrical. One side, the server, must indicate to the transport protocol that it can receive incoming connections via the listen function. The other side, the client, initiates the circuit with the connect function, and the server can obtain a socket for the circuit with the accept function. Once the circuit is established, data transfer takes place with the send and recv functions. Protocol-level activity results from this circuit establishment, and more protocol activity tears down the circuit when the sockets are closed. TCP and SPX are examples of connection-oriented transport protocols.

In a connectionless transport protocol, circuit establishment is not required for data transfer. An application need only open and bind a socket, after which it can use the sendto and recvfrom functions to send and receive data. Of course, in order to specify the remote address for sending data or the address from which received data was sent, you must specify a sockaddr to these routines. UDP and IPX are examples of connectionless transport protocols.

It is possible to use the connect function on sockets opened for connectionless protocols. This is merely an application convenience, allowing the application to use the send and recv functions, and this does not result in any protocol activity. If a socket is connected in this manner, it will receive only packets sent from the connected address; other packets destined for the socket are silently discarded.


Reliable vs. Unreliable Data Delivery

Most physical networks are inherently unreliable. They can drop data, corrupt it, deliver it out of order, and deliver multiple copies of it. Some transport protocols hide this unreliability from applications by using protocol-level mechanisms to ensure that data is delivered in the correct order, without loss, corruption, or duplication. Other transport protocols do not make these guarantees; they simply make a best effort to get the data to its intended recipient, but physical network failures can lead to data integrity problems.

Because they require fewer system resources and less processing, unreliable protocols often provide better performance, especially for applications that send small amounts of data in a request-response (transaction) format. However, applications that use connectionless protocols must guarantee reliability, which makes applications more complicated. Reliable protocols are usually simpler for the application at the expense of a higher cost in system resources and performance.

Typically, connection-oriented protocols are reliable, while connectionless protocols are unreliable. While this is true of all the transport protocols supported by Windows NT, there are exceptions.


Terminating a Virtual Circuit

For a connection-oriented transport protocol, there are two ways to terminate a virtual circuit: orderly and abortive. In an orderly release, both sides get a chance to indicate that they have sent all the data they intend to send, and only when both sides have finished is the actual circuit terminated. For such a release, one side can use the shutdown function to indicate that it has finished sending, while the other side continues sending. In an abortive termination of a virtual circuit, one side decides that it is time to terminate the circuit and unilaterally ends the connection. If the other side attempts to use the connected socket, the request fails.

By default, closesocket also attempts an orderly release of the connection. However, under several circumstances, such as pending unreceived, outstanding send calls, and more, a closesocket will result in an abortive close.

All transport protocols support the concept of an abortive release, but not all protocols support orderly release. If an application attempts an orderly release on a transport protocol that does not support orderly release, the connection is terminated abortively. TCP supports orderly release, while SPX supports only abortive release.


Message-Oriented vs. Stream-Oriented

Connection-oriented transport protocols can be either message-oriented or stream-oriented. In a message-oriented transport protocol, each block of data is sent and received as a single block. An individual message is never broken down when received, although a transport protocol can be forced to break down a message if it is larger than the physical network's maximum transmission unit (MTU). However, this is transparent to the application.

In a stream-oriented transport protocol, data is sent and received as a continuous stream, without any message boundaries. The transport protocol is free to coalesce data from discrete send calls and deliver it to a single recv call, as well as to break down the data buffer given to a single send call and deliver it to several recv calls. An application cannot control how these breakdowns occur, and gets no notification of how data was sent. If an application needs to communicate in discrete messages, it must frame them, for example, by preceding message data with the length of the message until the specified length arrives.

Some message-oriented protocols support stream semantics in addition to message semantics. If an application opens a socket with SOCK_STREAM on such a transport protocol, then the transport ignores all message boundaries when transmitting and receiving data. It simply delivers data as it becomes available, without any regard to whether the data is a complete message. This feature is handy for maximizing application portability. Note, however, that stream-oriented transport protocols cannot implement message-oriented semantics due to lack of information.


Expedited Data

Some connection-oriented transport protocols support expedited data, also referred to as "urgent data" or "out-of-band data." Data sent with the MSG_OOB flag in the send function is sent as expedited data, and the transport protocol makes every effort to deliver the data as quickly as possible. Often the data is delivered out of order so that it can get to the other application as quickly as possible. For maximum portability, avoid expedited data since it is not supported by all transport protocols.


Connect and Disconnect Data

A few transport protocols support connect and disconnect data, in which a small amount of data is sent by each side when a virtual circuit is established or terminated. This data can be anything, but is often negotiation information about the version of software connecting, and so on. Again, for protocol portability, avoid this feature since it is not universally supported.


Broadcasts

Most connectionless transport protocols support broadcasts in the same fashion, in which any bound socket can send a broadcast if the SO_BROADCAST option is set, and broadcasts sent to the appropriate local endpoint are received without any additional work on the part of the application. NetBIOS transport protocols, however, handle broadcasts somewhat differently. In order to receive broadcasts, an application must bind to the NetBIOS broadcast address, which is an asterisk ("*") followed by 15 blank spaces (ASCII character 0x20). This means two things: A socket must be specially bound to receive broadcasts, and applications cannot depend on receiving broadcasts intended only for a specific application, since all NetBIOS broadcasts are delivered to this address. In other protocols such as UDP/IP and IPX, broadcasts are delivered to a socket only if the broadcast was sent to the same port to which the socket was bound.


Extended Support for Message-Oriented Protocols

The BSD sockets interface was originally designed to support primarily TCP/IP, and the Windows Sockets interface is based on BSD sockets. This interface is not sufficiently rich for message-oriented transport protocols, however, so Windows NT includes some minor extensions of the interface so that applications can fully exploit message-oriented transport protocols.


MSG_PARTIAL Flag

Under some circumstances, applications may not have available in a single, contiguous data buffer all the data that make up a single message to be sent. The message can be very large, for example, or can be composed of discrete parts in an application's virtual address space. To allow an application to send this message without having to allocate a buffer and copy all the data into the buffer, Windows NT allows the application to specify the MSG_PARTIAL bit in the flags parameter of the send function. This bit tells the transport protocol that the data in the send operation is just part of a larger message, and that the protocol should take whatever action is necessary to deliver the data as a partial message.


WSARecvEx API

By default, for message-oriented transport protocols the Windows Sockets recv function receives a single message in each call to the API. This works fine for most cases, but there are two situations in which this is insufficient: when the application's data buffer is smaller than the message, and when the message is large and arrives in several pieces.

When the buffer is smaller than the data, as much of the message as will fit is copied into the user's buffer and recv returns with the error code WSAEMSGSIZE. A subsequent call to recv will get the next part of the message. Applications written for message-oriented transport protocols should be coded for this possibility if message sizing is not guaranteed by the application's data transfer protocol. If an application gets this error code, then the entire data buffer is filled with data.

It is more complicated when a very large message arrives a little at a time. For example, if an application sends a 1-megabyte message, the transport protocol must break up the message in order to send it over the physical network. It is theoretically possible for the transport protocol on the receiving side to buffer all the data in the message, but this would be quite expensive in terms of resources.

It would be better to allow a recv call to complete with only a partial message and some indication to the application that the data is only a partial message. However, the Windows Sockets recv function has only one output parameter: the number of bytes received. Therefore, Windows NT supplies the WSARecvEx function, which is identical to the recv function except that the flags parameter is an in-out parameter:

int PASCAL FAR WSARecvEx (SOCKET s, char FAR * buf, int len, int *flags);

On return from WSARecvEx, if a partial message was received, the MSG_PARTIAL bit is set in the flags parameter. If a complete message was received, MSG_PARTIAL is not set in flags. For a stream-oriented transport protocol, MSG_PARTIAL is never set on return from WSARecvEx; for stream transport protocols this function behaves identically to the normal recv function.


WSAEDISCON Error Code

After a virtual circuit is gracefully terminated on a stream-oriented transport protocol and all data has been received, the recv and WSARecvEx functions return zero to indicate that there will never be any more data to read on the connection. However, most message-oriented transport procotols support the concept of a zero-length message. Applications therefore need a mechanism to distinguish a zero-length message and graceful circuit termination.

The Windows Sockets interface in Windows NT uses the WSAEDISCON error code to solve this problem. When the circuit is gracefully terminated, this error code is returned to the application, and a return value of zero is used to indicate a message of length zero.

Following is an example of client-side code that establishes an SPX connection, and receives and processes messages until the connection is terminated.

SOCKET s;

SOCKADDR_IPX sockaddrIpx;

INT err;

INT bytesReceived;

INT flags;

/* open the SPX socket handle */

s = socket( AF_IPX, SOCK_SEQPACKET, NSPROTO_SPX );

/* initialize the sockaddr for the remote machine */

sockaddrIpx.sa_family = AF_IPX;

sockaddrIpx.sa_netnum = 0;

sockaddrIpx.sa_nodenum = 123;  /* substitute real nodenum here */

sockaddrIpx.sa_socket = 1; /*substitute real socket number here */

/* connect the socket */

err = connect( s, (PSOCKADDR)&sockaddrIpx, sizeof(sockaddrIpx) );

if ( err != 0 ) {

    /* indicate connection failure */

}

/* receive data until the connection terminates */

while ( TRUE ) {

    /* use WSARecvEx to receive data */

    flags = 0;

    bytesReceived = WSARecvEx( s, buffer, buflen, &flags );

    /* check for error or graceful termination */

    if ( bytesReceived < 0 ) {

        if ( WSAGetLastError( ) == WSAEDISCON ) {

            /* graceful termination */

            break;

        }

        /* some other error, indicate to user */

        break;

    }

    /* check for partial message */

    if ( (flags & MSG_PARTIAL) != 0 ) {

        /* a partial message; handle specially */

    }

    /* check for 0-length message */

    if ( bytesReceived == 0 ) {

        /* 0-length message, process */

    } else {

        /* message contained data */

    }

}

/* circuit terminated or error, close socket */

closesocket( s );


Windows NT Support for Connect and Disconnect Data

Some transport protocols, such as DECNet and OSI TP4, support the concept of connect and disconnect data. This is additional data, not in the normal data stream, which is sent on the wire along with connect or disconnect requests and is typically used for things like application-level version negotiation. The TDI interface provides support for connect and disconnect data through the TDI_CONNECTION_INFORMATION structure, which has fields for UserDataLength, UserData, OptionsLength, and Options and is passed on TDI connect, accept, and disconnect requests.

The sockets interface, however, does not provide input parameters for connect data on the connect function or for disconnect data on the shutdown and closesocket functions. However, it is relatively natural to use the setsockopt function to specify connect and disconnect data to send, and to use the getsockopt function to retrieve connect and disconnect data sent by the remote side. To support this, the following socket options are included with the Windows NT version of the Windows Sockets header file (WINSOCK.H):

/*

 * Options for connect and disconnect data and options. Used only by

 * non-TCP/IP transports such as DECNet, OSI TP4, etc.

 */

#define SO_CONNDATA     0x7000

#define SO_CONNOPT      0x7001

#define SO_DISCDATA     0x7002

#define SO_DISCOPT      0x7003

#define SO_CONNDATALEN  0x7004

#define SO_CONNOPTLEN   0x7005

#define SO_DISCDATALEN  0x7006

#define SO_DISCOPTLEN   0x7007

How an application uses these options in conjunction with getsockopt and setsockopt depends on the type of application, server or client, and how it will use connect data. Each case is explained following.

Connect and disconnect options are semantically the same as connect and disconnect data, from the standpoint of the Windows Sockets interface. The "options" are really just a buffer of data that is passed to the transport protocol prior to the connect or disconnect, and a buffer that is retrieved following a connect or disconnect. Therefore, an application uses connect or disconnect options in much the same manner it uses connect or disconnect data. The only difference is the option names used on the getsockopt and setsockopt calls; for example, use SO_CONNOPT in place of SO_CONNDATA.


Client Applications and Connect Data

A Windows Sockets client application written for a transport protocol that supports connect data should call setsockopt with SOL_SOCKET as the level, SO_CONNDATA as the option name, and a buffer in the option value field that contains the connect data it intends to send. This call must be made before calling the connect function. The specified connect data is then sent on the connect request.

Two steps are required to retrieve response connect data. First, before the connect call, the application must inform the Windows Sockets DLL how much space to reserve for the response connect data. This is done by calling setsockopt with option level SOL_SOCKET, option name SO_CONNDATALEN, and having the option value parameter point to an integer that contains the maximum number of connect data bytes expected. The Windows Sockets DLL will set aside a buffer of this size to contain connect data sent by the server application.

After the connect has completed successfully, the application can call getsockopt with an option level of SOL_SOCKET, an option name of SO_CONNDATA, and a buffer in the option value parameter large enough to hold the response connect data. The Windows Sockets DLL then copies the response connect data into the caller's buffer.

Note that the Windows Sockets DLL keeps the response connect data buffer valid for the lifetime of the socket. Therefore, an application can retrieve the response connect data for the socket at any time after the socket is connected and before it is closed.


Server Applications and Connect Data

A server application's use of connect data implicitly differs in two important ways from a client application's use. First, a server application receives the client's connect data before it sends its own. Second, because the socket's interface does not support the concept of delayed accept, a server application is limited to sending the same response connect data to all clients.

A server application that is to receive connect data should use setsockopt with the SO_CONNDATALEN option to force the Windows Sockets DLL to reserve buffer space into which to receive connect data for incoming connect requests. The specified amount of connect data buffer space is used for all incoming connects, but each connect gets a separate buffer. After a new connected socket is accepted with accept the application calls getsockopt with the SO_CONNDATA option and a buffer large enough to hold expected response data. The Windows Sockets DLL fills in this buffer with the connect data sent by the client.

To send connect data, a server application calls setsockopt with the SO_CONNDATA option and a buffer of data before incoming connections are accepted (typically before listen). Thereafter, any client that connects to the server will receive the specified connect data. The connect data sent by a server can be changed at any time with another setsockopt call, which discards the previous data and replaces it with new connect data.


Disconnect Data

Client and server applications send and receive disconnect data in a manner similar to the way a client application sends and receives connect data. To send disconnect data the application calls setsockopt with the SO_DISCDATA option and a buffer of disconnect data to send. The data will then be sent either when the application calls shutdown to disconnect the send side of the socket or when the application calls closesocket on the socket.

To receive disconnect data, an application must call setsockopt with the SO_DISCDATALEN option before a remote closes the connection. This option specifies the amount of disconnect data the application expects to receive.

After the remote has disconnected, the SO_DISCDATA option on getsockopt retrieves the disconnect data sent by the remote . The application passes in a buffer large enough to hold all the disconnect data, and the Windows Sockets DLL copies the received disconnect data into the buffer.


Individual Protocol Features

Forthcoming


TCP/IP

Forthcoming


IPX/SPX

Forthcoming


Appletalk

Forthcoming


OSI TP4

Forthcoming


DECNet

Forthcoming


Netbios Providers

Forthcoming


Additional Items

The following sections provide details on additional items in Windows Sockets.


Blocking Sockets Calls

The Windows Sockets specification defines a "blocking hook" mechanism, accessed through the WSASetBlockingHook, WSAUnhookBlockingHook, WSAIsBlocking, and WSACancelBlockingCall functions. The blocking hook works by polling for Windows messages while a Windows Sockets API call is blocking on network activity and calling back into the application when a message arrives. This mechanism allows a measure of multitasking to occur within the nonpreemptive Windows environment. In fact, an application that makes blocking calls gets a "default blocking hook" installed, which can result in reentrance to the application if the application makes any calls that must block. (For more detailed information on the blocking hook semantics, see the Windows Sockets specification in the Windows NT SDK.)

The blocking hook is useful for promoting multitasking, but Windows NT, being a fully preemptive, multitasking operating system, doesn't need any help from applications to do multitasking. Additionally, programming Windows applications that use the blocking is complex, requiring special attention to reentrance issues. Therefore, 32-bit applications for Windows NT do not get a default blocking hook installed. If a thread makes a blocking call, the thread simply blocks, and the system schedules other threads as appropriate, waking up the blocked thread when the I/O completes.

If a 32-bit application really does require the blocking hook semantics, such an application can use WSASetBlockingHook to install any blocking hook on a per-thread basis. This blocking hook will operate exactly as specified in the Windows Sockets specification. Note that the fact that the blocking hook is per-thread means two things for multithreaded applications: If they need blocking hooks, they must install a blocking hook for every thread that makes blocking Windows Sockets calls; and they can install a different blocking hook in different threads of their process, allowing different blocking hook behavior in different threads.

If a 16-bit application is ported to Win32 and depends on the behavior of the default blocking hook, the application can install as a blocking hook code that performs the same actions as the default blocking hook:

BOOL

DefaultBlockingHook (

    VOID

    )

{

    MSG msg;

    BOOLEAN retrievedMessage;

    //

    // Get the next message, if any.

    //

    retrievedMessage = PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );

    //

    // Process the message if we got one.

    //

    if ( retrievedMessage ) {

        TranslateMessage( (CONST MSG *)&msg );

        DispatchMessage( (CONST MSG *)&msg );

    }

    //

    // If we got a message, indicate that we want to be called again.

    //

    return retrievedMessage;

} // DefaultBlockingHook

Note that 16-bit Windows Sockets applications running in the 16-bit subsystem of Windows NT do get the default blocking hook semantics as described in the Windows Sockets specification, so there is no need to modify 16-bit applications to take advantage of the blocking hook behavior.


WSAGetLastError vs. GetLastError

Windows Sockets applications use the WSAGetLastError function to retrieve specific error information on failed API calls. For 32-bit applications under Windows NT, the WSAGetLastError function is just a call through to theWin32 GetLastError call, which provides identical functionality. Therefore, if an application makes a Windows Sockets call that fails, then a Win32 API call that also fails, the result of WSAGetLastError will give the error code for the Win32 API failure. In addition, some C run-time calls, specifically printf, reset the thread's last error to zero, so a call to WSAGetLastError after one of these API calls can return the value zero rather than the actual failure code. It is strongly recommended that applications be written to call WSAGetLastError (or GetLastError) immediately after a failed Windows Sockets call is detected without any intervening API calls.

Note also that WSASetLastError is just a call through to SetLastError, so calling WSASetLastError will reset the error obtained by GetLastError.


Closing Sockets: Graceful vs. Abortive

For transport protocols that support graceful close, Windows NT has been carefully designed to perform graceful closes when appropriate, and to perform abortive closes when appropriate. By default, closing a connected socket with closesocket results in a graceful close of the virtual circuit. In addition, using shutdown on the send side of a socket initiates a graceful close. If an application is to force an abortive close, it should set the SO_LINGER option on the socket to have a timeout of zero.

Windows NT uses an abortive close to indicate to the remote end that a connection was terminated in an ungraceful manner. There are several causes for this:

•	Closing a socket when there is unreceived data buffered on the socket.

•	Exiting a process without calling closesocket on all connected sockets.

•	Data arrives after the graceful close has been initiated.

•	The SO_LINGER option is nonzero, but some data remains unsent after the timeout expires.

To ensure a graceful close on a virtual circuit, an application must receive all data on the socket and manually call closesocket on the socket. To do this properly, some application protocols require the shutdown function to initiate graceful close in conjunction with recv or WSARecvEx to ensure that all data sent by the remote is received locally.


Notes on Performance

Many Windows Sockets developers are very interested in application performance. They want to transfer data as quickly as possible with minimal burden on the system CPU. This is a difficult art, worthy of a paper on its own. However, there are several general guidelines that can help application developers tune their code. Many of these simple guidelines will seem obvious, but it is surprising how often they are overlooked, leading developers to wonder why their applications are so slow.

First, send and receive data in chunks as large as possible, up to approximately 64 kilobytes. There is a certain amount of unavoidable overhead in each send or recv call, and sending and receiving large chunks of data spreads the overhead over fewer calls.

Second, do as little in performance paths as possible. Do not include any extraneous calls, either Windows Sockets or Win32. If you need to send a lot of data, do it in a tight loop without any calls other than send. If you must specify a timeout on the send, do not use the select function, which has the inherent overhead of a kernel transition. Instead, set the SO_SNDTIMEO option on the socket and use send only. If you're handling several sockets in your application, use threads so that you can avoid calls to select (but be careful not to use too many threads — threads cost memory and introduce context switching overhead).

It is possible to achieve very high data transfer rates with the Windows Sockets interface in Windows NT. With TCP/IP on a 10-megabit-per-second ethernet, we have seen rates of mroe than a megabyte per second, which is close to the theoretical maximum for the medium, and the system CPUs were not fully saturated. This demonstrates that in a carefully coded and tuned application it is possible to achieve excellent performance through Windows Sockets.


Windows NT Extensions to WINSOCK.H

To support some of the features unique to Windows NT described in this document, the WINSOCK.H header file that is included with the Windows NT SDK contains some additional information. This additional information is provided following for those lacking access to the Windows NT SDK.

/*

 * Options for connect and disconnect data and options. Used only by

 * non-TCP/IP transports such as DECNet, OSI TP4, etc.

 */

#define SO_CONNDATA     0x7000

#define SO_CONNOPT      0x7001

#define SO_DISCDATA     0x7002

#define SO_DISCOPT      0x7003

#define SO_CONNDATALEN  0x7004

#define SO_CONNOPTLEN   0x7005

#define SO_DISCDATALEN  0x7006

#define SO_DISCOPTLEN   0x7007

/*

 * Option for opening sockets for synchronous access.

 */

#define SO_OPENTYPE     0x7008

#define SO_SYNCHRONOUS_ALERT    0x10

#define SO_SYNCHRONOUS_NONALERT 0x20

#define WSAEDISCON              (WSABASEERR+101)

int PASCAL FAR WSARecvEx (SOCKET s, char FAR * buf, int len, int *flags);


Acknowledgments

The authors would like to thank their companies for allowing them the time and resources to make this specification possible: JSB Corporation, Microdyne Corporation, FTP Software, Sun Microsystems, and Microsoft Corporation.

Special thanks should also be extended to the other efforts contributing to the success of Windows Sockets. The original draft was heavily influenced by existing specifications offered and detailed by JSB Corporation and Net Manage, Inc. The "version 1.0 debate" hosted by Microsoft in Seattle allowed many of the members of the working group to hash out final details for 1.0 vis-a-vis.

Sun Microsystems was kind enough to allow first time implementors to "plug and play" beta software during the first Windows Sock-A-Thon of Windows Sockets applications and implementations at Interop Fall '92. Microsoft has shared WSAT (the Windows Sockets API Tester) with other Windows Sockets implementors as a standard Windows Sockets test suite to aid in testing their implementations. Finally, Sun Microsystems and FTP Software plan to host the Windows Sock-A-Thon II in Boston February '93.

Without the contributions of the individuals and corporations involved in the working group, Windows Sockets would never have been as thoroughly reviewed and completed as quickly. In just one year, several competitors in the networking business developed a useful specification with something to show for it! Many thanks to all which participated, either in person or on e-mail to the Windows Sockets effort. The authors would like to thank everyone who participated in any way, and apologize in advance for anyone we have omitted.

List of contributors:

Martin Hall,  Chairman	JSB Corporation	martinh@jsbus.com
Mark Towfiq,  Coordinator	Microdyne Corporation	towfiq@microdyne.com
Geoff Arnold,  Editor 1.0	Sun Microsystems	geoff@east.sun.com
David Treadwell,  Editor 1.1	Microsoft Corporation	davidtr@microsoft.com
Henry Sanders	Microsoft Corporation	henrysa@microsoft.com
J. Allard	Microsoft Corporation	jallard@microsoft.com
Chris Arap-Bologna	Distinct	chris@distinct.com
Larry Backman	FTP Software	backman@ftp.com
Alistair Banks	Microsoft Corporation	alistair@microsoft.com
Rob Barrow	JSB Corporation	robb@jsb.co.uk
Carl Beame	Beame & Whiteside	beame@mcmaster,ca
Dave Beaver	Microsoft Corporation	dbeaver@microsoft.com
Amatzia BenArtzi	NetManage, Inc.	amatzia@netmanage.com
Mark Beyer	Ungermann-Bass	mbeyer@ub.com
Nelson Bolyard	Silicon Graphics, Inc.	nelson@sgi.com
Pat Bonner	Hewlett-Packard	p_bonner@cnd.hp.com
Derek Brown	FTP Software	db@wco.ftp.com
Malcolm Butler	ICL	mcab@oasis.icl.co.uk
Mike Calbaum	Fronteir Technologies	mike@frontiertech.com
Isaac Chan	Microsoft Corporation	isaacc@microsoft.com
Khoji Darbani	Informix	khoji@informix.com
Nestor Fesas	Hughes LAN Systems	nestor@hls.com
Karanja Gakio	FTP Software	karanja@ftp.com
Vikas Garg	Distinct	vikas@distinct.com
Gary Gere	Gupta	ggere@gupta.com
Jim Gilroy	Microsoft Corporation	jamesg@microsoft.com
Bill Hayes	Hewlett-Packard	billh@hpchdpc.cnd.hp.com
Paul Hill	MIT	pbh@athena.mit.edu
Tmima Koren	Net Manage, Inc.	tmima@netmanage.com
Hoek Law	Citicorp	law@dcc.tti.com
Graeme Le Roux	Moresdawn P/L	-
Kevin Lewis	Novell	kevinl@novell.com
Roger Lin	3Com	roger_lin@3mail.3com.com
Terry Lister	Hewlett-Packard	tel@cnd.hp.com
Jeng Long Jiang	Wollongong	long@twg.com
Lee Murach	Network Research	lee@nrc.com
Pete Ostenson	Microsoft Corporation	peteo@microsoft.com
David Pool	Spry, Inc.	dave@spry.com
Bob Quinn	FTP Software	rcq@ftp.com
Glenn Reitsma	Hughes LAN Systems	glennr@hls.com
Brad Rice	Age	rice@age.com
Allen Rochkind	3Com	-
Jonathan Rosen	IBM	jrosen@vnet.ibm.com
Steve Stokes	Novell	stoke@novell.com
Joseph Tsai	3Com	joe_tsai@3mail.3com.com
James Van Bokkelen	FTP Software	jbvb@ftp.com
Miles Wu	Wollongong	wu@twg.com
Boris Yanovsky	NetManage, Inc.	boris@netmanage.com


Introduction to Windows Sockets

What is Windows Sockets?

The Windows Sockets specification defines a network programming interface for Microsoft Windows (Windows is a trademark of Microsoft Corporation) which is based on the "socket" paradigm popularized in the Berkeley Software Distribution (BSD) from the University of California at Berkeley. It encompasses both familiar Berkeley socket style routines and a set of Windows-specific extensions designed to allow the programmer to take advantage of the message-driven nature of Windows.

The Windows Sockets Specification is intended to provide a single API to which application developers can program and multiple network software vendors can conform. Furthermore, in the context of a particular version of Microsoft Windows, it defines a binary interface (ABI) such that an application written to the Windows Sockets API can work with a conformant protocol implementation from any network software vendor. This specification thus defines the library calls and associated semantics to which an application developer can program and which a network software vendor can implement.

Network software which conforms to this Windows Sockets specification will be considered "Windows Sockets Compliant". Suppliers of interfaces which are "Windows Sockets Compliant" shall be referred to as "Windows Sockets Suppliers". To be Windows Sockets Compliant, a vendor must implement 100% of this Windows Sockets specification.

Applications which are capable of operating with any "Windows Sockets Compliant" protocol implementation will be considered as having a "Windows Sockets Interface" and will be referred to as "Windows Sockets Applications".

This version of the Windows Sockets specification defines and documents the use of the API in conjunction with the Internet Protocol Suite (IPS, generally referred to as TCP/IP). Specifically, all Windows Sockets implementations support both stream (TCP) and datagram (UDP) sockets.

While the use of this API with alternative protocol stacks is not precluded (and is expected to be the subject of future revisions of the specification), such usage is beyond the scope of this version of the specification.


Berkeley Sockets

The Windows Sockets Specification has been built upon the Berkeley Sockets programming model which is the de facto standard for TCP/IP networking. It is intended to provide a high degree of familiarity for programmers who are used to programming with sockets in UNIX and other environments, and to simplify the task of porting existing sockets-based source code. The Windows Sockets API is consistent with release 4.3 of the Berkeley Software Distribution (4.3BSD).

Portions of the Windows Sockets specification are derived from material which is Copyright (c) 1982-1986 by the Regents of the University of California. All rights are reserved. The Berkeley Software License Agreement specifies the terms and conditions for redistribution.


Microsoft Windows and Windows-specific Extensions

This API is intended to be usable within all implementations and versions of Microsoft Windows from Microsoft Windows Version 3.0 onwards. It thus provides for Windows Sockets implementations and Windows Sockets applications in both 16 and 32 bit operating environments.

Windows Sockets makes provisions for multithreaded Windows processes. A process contains one or more threads of execution. In the Windows 3.1 non-multithreaded world, a task corresponds to a process with a single thread. All references to threads in this document refer to actual "threads" in multithreaded Windows environments. In non multithreaded environments (such as Windows 3.0), use of the term thread refers to a Windows process.

The Microsoft Windows extensions included in Windows Sockets are provided to allow application developers to create software which conforms to the Windows programming model. It is expected that this will facilitate the creation of robust and high-performance applications, and will improve the cooperative multitasking of applications within non-preemptive versions of Windows. With the exception of WSAStartup and WSACleanup their use is not mandatory.


The Status of This Specification

Windows Sockets is an independent specification which was created and exists for the benefit of application developers and network vendors and, indirectly, computer users. Each published (non-draft) version of this specification represents a fully workable API for implementation by network vendors and programming use by application developers. Discussion of this specification and suggested improvements continue and are welcomed. Such discussion occurs mainly via the Internet electronic mail forum winsock@microdyne.com. Meetings of interested parties occur on an irregular basis. Details of these meetings are publicized to the electronic mail forum.


Revision History

Windows Sockets Version 1.0

Windows Sockets Version 1.0 represented the results of considerable work within the vendor and user community as discussed in For Further Reference. This version of the specification was released so that network software suppliers and application developers could begin to construct implementations and applications that conformed to the Windows Sockets standard.


Windows Sockets Version 1.1

Windows Sockets Version 1.1 follows the guidelines and structure laid out by version 1.0, making changes only where absolutely necessary as indicated by the experiences of a number of companies that created Windows Sockets implementations based on the version 1.0 specification. Version 1.1 contains several clarifications and minor fixes to version 1.0. Additionally, the following more significant changes were incorporated into version 1.1:

•	Inclusion of the gethostname routine to simplify retrieval of the host's name and address.

•	Definition of DLL ordinal values below 1000 as reserved for Windows Sockets and ordinals above 1000 as unrestricted. This allows Windows Sockets vendors to include private interfaces to their DLLs without risking that the ordinals chosen will conflict with a future version of Windows Sockets.

•	Addition of a reference count to WSAStartup and WSACleanup, requiring correspondences between the calls. This allows applications and third-party DLLs to make use of a Windows Sockets implementation without being concerned about the calls to these APIs made by the other.

•	Change of return type of inet_addr from struct in_addr to unsigned long. This was required due to different handling of four-byte structure returns between the Microsoft and Borland C compilers.

•	Change of WSAAsyncSelect semantics from "edge-triggered" to "level-triggered". The level-triggered semantics significantly simplify an application's use of this routine.

•	Change the ioctlsocket FIONBIO semantics to fail if a WSAAsyncSelect call is outstanding on the socket.

•	Addition of the TCP_NODELAY socket option for RFC 1122 conformance.


Programming with Sockets

Windows Sockets Stack Installation Checking

To detect the presence of one (or many) Windows Sockets implementations on a system, an application which has been linked with the Windows Sockets Import Library may simply call the WSAStartup routine. If an application wishes to be a little more sophisticated it can examine the $PATH environment variable and search for instances of Windows Sockets implementations (WINSOCK.DLL). For each instance it can issue a LoadLibrary call and use the WSAStartup routine to discover implementation specific data.

This version of the Windows Sockets specification does not attempt to address explicitly the issue of multiple concurrent Windows Sockets implementations. Nothing in the specification should be interpreted as restricting multiple Windows Sockets DLLs from being present and used concurrently by one or more Windows Sockets applications.

For further details of where to obtain Windows Sockets components, see Windows Sockets Components


Sockets

The material in this guide is derived from the document "An Advanced 4.3BSD Interprocess Communication Tutorial" by Samuel J. Leffler, Robert S. Fabry, William N. Joy, Phil Lapsley, Steve Miller, and Chris Torek.


Basic Concepts

The basic building block for communication is the socket. A socket is an endpoint of communication to which a name may be bound. Each socket in use has a type and an associated process. Sockets exist within communication domains. A communication domain is an abstraction introduced to bundle common properties of threads communicating through sockets. Sockets normally exchange data only with sockets in the same domain (it may be possible to cross domain boundaries, but only if some translation process is performed). The Windows Sockets facilities support a single communication domain: the Internet domain, which is used by processes which communicate using the Internet Protocol Suite. (Future versions of this specification may include additional domains.)

Sockets are typed according to the communication properties visible to a user. Applications are presumed to communicate only between sockets of the same type, although there is nothing that prevents communication between sockets of different types should the underlying communication protocols support this.

Two types of sockets currently are available to a user. A stream socket provides for the bi-directional, reliable, sequenced, and unduplicated flow of data without record boundaries.

A datagram socket supports bi-directional flow of data which is not promised to be sequenced, reliable, or unduplicated. That is, a process receiving messages on a datagram socket may find messages duplicated, and, possibly, in an order different from the order in which it was sent. An important characteristic of a datagram socket is that record boundaries in data are preserved. Datagram sockets closely model the facilities found in many contemporary packet switched networks such as Ethernet.


Client-server model

The most commonly used paradigm in constructing distributed applications is the client/server model. In this scheme client applications request services from a server application. This implies an asymmetry in establishing communication between the client and server.

The client and server require a well-known set of conventions before service may be rendered (and accepted). This set of conventions comprises a protocol which must be implemented at both ends of a connection. Depending on the situation, the protocol may be symmetric or asymmetric. In a symmetric protocol, either side may play the master or slave roles. In an asymmetric protocol, one side is immutably recognized as the master, with the other as the slave. An example of a symmetric protocol is the TELNET protocol used in the Internet for remote terminal emulation. An example of an asymmetric protocol is the Internet file transfer protocol, FTP. No matter whether the specific protocol used in obtaining a service is symmetric or asymmetric, when accessing a service there is a "client process" and a "server process".

A server application normally listens at a well-known address for service requests. That is, the server process remains dormant until a connection is requested by a client's connection to the server's address. At such a time the server process "wakes up" and services the client, performing whatever appropriate actions the client requests of it. While connection-based services are the norm, some services are based on the use of datagram sockets.


Out-of-band data

Note: The following discussion of out-of-band data, also referred to as TCP Urgent data, follows the model used in the Berkeley software distribution. Users and implementors should be aware of the fact that there are at present two conflicting interpretations of RFC 793 (in which the concept is introduced), and that the implementation of out-of-band data in the Berkeley Software Distribution does not conform to the Host Requirements laid down in RFC 1122. To minimize interoperability problems, applications writers are advised not to use out-of-band data unless this is required in order to interoperate with an existing service. Windows Sockets suppliers are urged to document the out-of-band semantics (BSD or RFC 1122) which their product implements. It is beyond the scope of this specification to mandate a particular set of semantics for out-of-band data handling.

The stream socket abstraction includes the notion of "out of band" data. Out-of-band data is a logically independent transmission channel associated with each pair of connected stream sockets. Out-of-band data is delivered to the user independently of normal data. The abstraction defines that the out-of-band data facilities must support the reliable delivery of at least one out-of-band message at a time. This message may contain at least one byte of data, and at least one message may be pending delivery to the user at any one time. For communications protocols which support only in-band signaling (i.e. the urgent data is delivered in sequence with the normal data), the system normally extracts the data from the normal data stream and stores it separately. This allows users to choose between receiving the urgent data in order and receiving it out of sequence without having to buffer all the intervening data. It is possible to "peek" at out-of-band data.

An application may prefer to process out-of-band data "in-line", as part of the normal data stream. This is achieved by setting the socket option SO_OOBINLINE (see setsockopt). In this case, the application may wish to determine whether any of the unread data is "urgent" (the term usually applied to in-line out-of-band data). To facilitate this, the Windows Sockets implementation will maintain a logical "mark" in the data stream indicate the point at which the out-of-band data was sent. An application can use the SIOCATMARK ioctlsocket command to determine whether there is any unread data preceding the mark. For example, it might use this to resynchronize with its peer by ensuring that all data up to the mark in the data stream is discarded when appropriate.

The WSAAsyncSelect routine is particularly well suited to handling notification of the presence of out-of-band-data.


Broadcasting

By using a datagram socket, it is possible to send broadcast packets on many networks supported by the system. The network itself must support broadcast: the system provides no simulation of broadcast in software. Broadcast messages can place a high load on a network, since they force every host on the network to service them. Consequently, the ability to send broadcast packets has been limited to sockets which are explicitly marked as allowing broadcasting. Broadcast is typically used for one of two reasons: it is desired to find a resource on a local network without prior knowledge of its address, or important functions such as routing require that information be sent to all accessible neighbors.

The destination address of the message to be broadcast depends on the network(s) on which the message is to be broadcast. The Internet domain supports a shorthand notation for broadcast on the local network, the address INADDR_BROADCAST. Received broadcast messages contain the senders address and port, as datagram sockets must be bound before use.

Some types of network support the notion of different types of broadcast. For example, the IEEE 802.5 token ring architecture supports the use of link-level broadcast indicators, which control whether broadcasts are forwarded by bridges. The Windows Sockets specification does not provide any mechanism whereby an application can determine the type of underlying network, nor any way to control the semantics of broadcasting.


Byte Ordering

The Intel byte ordering is like that of the DEC VAX , and therefore differs from the Internet and 68000-type processor byte ordering. Thus care must be taken to ensure correct orientation.

Any reference to IP addresses or port numbers passed to or from a Windows Sockets routine must be in network order. This includes the IP address and port fields of a struct sockaddr_in (but not the sin_family field).

Consider an application which normally contacts a server on the TCP port corresponding to the "time" service, but which provides a mechanism for the user to specify that an alternative port is to be used. The port number returned by getservbyname is already in network order, which is the format required constructing an address, so no translation is required. However if the user elects to use a different port, entered as an integer, the application must convert this from host to network order (using the htons function) before using it to construct an address. Conversely, if the application wishes to display the number of the port within an address (returned via, e.g., getpeername), the port number must be converted from network to host order (using ntohs) before it can be displayed.

Since the Intel and Internet byte orders are different, the conversions described above are unavoidable. Application writers are cautioned that they should use the standard conversion functions provided as part of the Windows Sockets API rather than writing their own conversion code, since future implementations of Windows Sockets are likely to run on systems for which the host order is identical to the network byte order. Only applications which use the standard conversion functions are likely to be portable.


Socket Options

The socket options supported by Windows Sockets are listed in setsockopt and getsockopt. A Windows Sockets implementation must recognize all of these options, and (for getsockopt) return plausible values for each. The default value for each option is shown in the following table.

Value	Type	Meaning	Default	Note
SO_ACCEPTCONN	BOOL	Socket is listening.	FALSE unless a listen has been performed
SO_BROADCAST	BOOL	Socket is configured for the transmission of broadcast messages.	FALSE
SO_DEBUG	BOOL	Debugging is enabled.	FALSE	(i)
SO_DONTLINGER	BOOL	If true, the SO_LINGER option is disabled.	TRUE
SO_DONTROUTE	BOOL	Routing is disabled.	FALSE	(i)
SO_ERROR	int	Retrieve error status and clear.	0
SO_KEEPALIVE	BOOL	Keepalives are being sent.	FALSE
SO_LINGER	struct linger FAR *	Returns the current linger options.	l_onoff is 0
SO_OOBINLINE	BOOL	Out-of-band data is being received in the normal data stream.	FALSE
SO_RCVBUF	int	Buffer size for receives	Implementation dependent	(i)
SO_REUSEADDR	BOOL	The address to which this socket is bound can be used by others.	FALSE
SO_SNDBUF	int	Buffer size for sends	Implementation dependent	(i)
SO_TYPE	int	The type of the socket (e.g. SOCK_STREAM).	As created via socket
TCP_NODELAY	BOOL	Disables the Nagle algorithm for send coalescing.	Implementation dependent
Notes:

(i)  An implementation may silently ignore this option on setsockopt and return a constant value for getsockopt, or it may accept a value for setsockopt and return the corresponding value in getsockopt without using the value in any way.


Database Files

The getXbyY* and WSAAsyncGetXByY classes of routines are provided for retrieving network specific information. (This specification uses the function name getXbyY to represent the set of routines gethostbyaddr, gethostbyname, etc. Similarly WSAAsyncGetXByY represents WSAAsyncGetHostByAddr, etc.) The getXbyY routines were originally designed (in the first Berkeley UNIX releases) as mechanisms for looking up information in text databases. Although the information may be retrieved by the Windows Sockets implementation in different ways, a Windows Sockets application requests such information in a consistent manner through either the getXbyY or the WSAAsyncGetXByY class of routines.

*  This specification uses the function name getXbyY to represent the set of routines gethostbyaddr, gethostbyname, etc. Similarly WSAAsyncGetXByY represents WSAAsyncGetHostByAddr, etc.


Deviation from Berkeley Sockets

There are a few limited instances where the Windows Sockets API has had to divert from strict adherence to the Berkeley conventions, usually because of difficulties of implementation in a Windows environment.


Socket Data Type and Error Values

A new data type, SOCKET, has been defined. The definition of this type was necessary for future enhancements to the Windows Sockets specification, such as being able to use sockets as file handles in Windows NT. Definition of this type also facilitates porting of applications to a Win/32 environment, as the type will automatically be promoted from 16 to 32 bits.

In UNIX, all handles, including socket handles, are small, non-negative integers, and some applications make assumptions that this will be true. Windows Sockets handles have no restrictions, other than that the value INVALID_SOCKET is not a valid socket. Socket handles may take any value in the range 0 to INVALID_SOCKET-1.

Because the SOCKET type is unsigned, compiling existing source code from, for example, a UNIX environment may lead to compiler warnings about signed/unsigned data type mismatches.

This means, for example, that checking for errors when the socket and accept routines return should not be done by comparing the return value with -1, or seeing if the value is negative (both common, and legal, approaches in BSD). Instead, an application should use the manifest constant INVALID_SOCKET as defined in winsock.h. For example:

TYPICAL BSD STYLE:

s = socket(...);

if (s == -1)	/* or s < 0 */

{...}

PREFERRED STYLE:

s = socket(...);

if (s == INVALID_SOCKET)

{...}


select() and FD_*
select and FD_*

Because a SOCKET is no longer represented by the UNIX-style "small non-negative integer", the implementation of the select function was changed in the Windows Sockets API. Each set of sockets is still represented by the fd_set type, but instead of being stored as a bitmask the set is implemented as an array of SOCKETs. To avoid potential problems, applications must adhere to the use of the FD_XXX macros to set, initialize, clear, and check the fd_set structures.


Error codes - errno, h_errno & WSAGetLastError()
Error codes - errno, h_errno & WSAGetLastError

Error codes set by the Windows Sockets implementation are NOT made available via the errno variable. Additionally, for the getXbyY class of functions, error codes are NOT made available via the h_errno variable. Instead, error codes are accessed by using the WSAGetLastError . This function is provided in Windows Sockets as a precursor (and eventually an alias) for the Win32 function GetLastError. This is intended to provide a reliable way for a thread in a multi-threaded process to obtain per-thread error information.

For compatibility with BSD, an application may choose to include a line of the form:

#define errno WSAGetLastError

This will allow networking code which was written to use the global errno to work correctly in a single-threaded environment. There are, obviously, some drawbacks. If a source file includes code which inspects errno for both socket and non-socket functions, this mechanism cannot be used. Furthermore, it is not possible for an application to assign a new value to errno. (In Windows Sockets the function WSASetLastError may be used for this purpose.)

TYPICAL BSD STYLE:

r = recv(...);

if (r == -1

 && errno == EWOULDBLOCK)

{...}

PREFERRED STYLE:

r = recv(...);

if (r == -1 /* (but see below) */

 && WSAGetLastError == EWOULDBLOCK)

{...}

Although error constants consistent with 4.3 Berkeley Sockets are provided for compatibility purposes, applications should, where possible, use the "WSA" error code definitions. For example, a more accurate version of the above source code fragment is:

r = recv(...);

if (r == -1 /* (but see below) */

 && WSAGetLastError == WSAEWOULDBLOCK)

{...}


Pointers

All pointers used by applications with Windows Sockets should be FAR. To facilitate this, data type definitions such as LPHOSTENT are provided.


Renamed functions

In two cases it was necessary to rename functions which are used in Berkeley Sockets to avoid clashes with other APIs.

close & closesocket

In Berkeley Sockets, sockets are represented by standard file descriptors, and so the close function can be used to close sockets as well as regular files. While nothing in the Windows Sockets API prevents an implementation from using regular file handles to identify sockets, nothing requires it either. Socket descriptors are not presumed to correspond to regular file handles, and file operations such as read, write, and close cannot be assumed to work correctly when applied to sockets. Sockets must be closed by using the closesocket routine. Using the close routine to close a socket is incorrect and the effects of doing so are undefined by this specification.

ioctl & ioctlsocket

Various C language run-time systems use the ioctl routine for purposes unrelated to Windows Sockets. For this reason we have defined the routine ioctlsocket which is used to handle socket functions which in the Berkeley Software Distribution are performed using ioctl and fcntl.


Blocking routines & EINPROGRESS

Although blocking operations on sockets are supported under Windows Sockets, their use is strongly discouraged. Programmers who are constrained to use blocking mode − for example, as part of an existing application which is to be ported − should be aware of the semantics of blocking operations in Windows Sockets. See section 3.1.1 for more details.


Maximum Number of Sockets Supported

The maximum number of sockets supported by a particular Windows Sockets supplier is implementation specific. An application should make no assumptions about the availability of a certain number of sockets. This topic is addressed further in WSAStartup. However, independent of the number of sockets supported by a particular implementation is the issue of the maximum number of sockets which an application can actually make use of.

The maximum number of sockets which a Windows Sockets application can make use of is determined at compile time by the manifest constant FD_SETSIZE. This value is used in constructing the fd_set structures used in select. The default value in winsock.h is 64. If an application is designed to be capable of working with more than 64 sockets, the implementor should define the manifest FD_SETSIZE in every source file before including winsock.h. One way of doing this may be to include the definition within the compiler options in the makefile, for example adding -DFD_SETSIZE=128 as an option to the compiler command line for Microsoft C. It must be emphasized that defining FD_SETSIZE as a particular value has no effect on the actual number of sockets provided by a Windows Sockets implementation.


Include files

For ease of portability of existing Berkeley sockets based source code, a number of standard Berkeley include files are supported. However, these Berkeley header files merely include the winsock.h include file, and it is therefore sufficient (and recommended) that Windows Sockets application source files should simply include winsock.h.


Return values on API failure

The manifest constant SOCKET_ERROR is provided for checking API failure. Although use of this constant is not mandatory, it is recommended. The following example illustrates the use of the SOCKET_ERROR constant:

TYPICAL BSD STYLE:

r = recv(...);

if (r == -1 /* or r < 0 */

 && errno == EWOULDBLOCK)

{...}

PREFERRED STYLE:

r = recv(...);

if (r == SOCKET_ERROR

 && WSAGetLastError == WSAEWOULDBLOCK)

{...}


Raw Sockets

The Windows Sockets specification does not mandate that a Windows Sockets DLL support raw sockets, that is, sockets opened with SOCK_RAW. However, a Windows Sockets DLL is allowed and encouraged to supply raw socket support. A Windows Sockets-compliant application that wishes to use raw sockets should attempt to open the socket with the socket call, and if it fails either attempt to use another socket type or indicate the failure to the user.


Windows Sockets in Multithreaded Versions of Windows

The Windows Sockets interface is designed to work for both single-threaded versions of Windows (such as Windows 3.1) and preemptive multithreaded versions of Windows (such as Windows NT). In a multithreaded environment the sockets interface is basically the same, but the author of a multithreaded application must be aware that it is the responsibility of the application, not the Windows Sockets implementation, to synchronize access to a socket between threads. This is the same rule as applies to other forms of I/O such as file I/O. Failure to synchronize calls on a socket leads to unpredictable results; for example if there are two simultaneous calls to send, there is no guarantee as to the order in which the data will be sent.

Closing a socket in one thread that has an outstanding blocking call on the same socket in another thread will cause the blocking call to fail with WSAEINTR, just as if the operation were canceled. This also applies if there is a select call outstanding and the application closes one of the sockets being selected.

There is no default blocking hook installed in preemptive multithreaded versions of Windows. This is because the machine will not be blocked if a single application is waiting for an operation to complete and hence not calling PeekMessage or GetMessage which cause the application to yield in nonpremptive Windows. However, for backwards compatibility the WSASetBlockingHook call is implemented in multithreaded versions of Windows, and any application whose behavior depends on the default blocking hook may install their own blocking hook which duplicates the default hook's semantics, if desired.


Socket Library Overview

Socket Functions

The Windows Sockets specification includes the following Berkeley-style socket routines:

accept *	An incoming connection is acknowledged and associated with an immediately created socket. The original socket is returned to the listening state.
bind	Assign a local name to an unnamed socket.
closesocket *	Remove a socket from the per-process object reference table. Only blocks if SO_LINGER is set.
connect *	Initiate a connection on the specified socket.
getpeername	Retrieve the name of the peer connected to the specified socket.
getsockname	Retrieve the current name for the specified socket
getsockopt	Retrieve options associated with the specified socket.
htonl	Convert a 32-bit quantity from host byte order to network byte order.
htons	Convert a 16-bit quantity from host byte order to network byte order.
inet_addr	Converts a character string representing a number in the Internet standard "." notation to an Internet address value.
inet_ntoa	Converts an Internet address value to an ASCII string in "." notation i.e. "a.b.c.d".
ioctlsocket	Provide control for sockets.
listen	Listen for incoming connections on a specified socket.
ntohl	Convert a 32-bit quantity from network byte order to host byte order.
ntohs	Convert a 16-bit quantity from network byte order to host byte order.
recv*	Receive data from a connected socket.
recvfrom *	Receive data from either a connected or unconnected socket.
select *	Perform synchronous I/O multiplexing.
send *	Send data to a connected socket.
sendto *	Send data to either a connected or unconnected socket.
setsockopt	Store options associated with the specified socket.
shutdown	Shut down part of a full-duplex connection.
socket	Create an endpoint for communication and return a socket.
* The routine can block if acting on a blocking socket.


Blocking/Non blocking & Data Volatility

One major issue in porting applications from a Berkeley sockets environment to a Windows environment involves "blocking"; that is, invoking a function which does not return until the associated operation is completed. The problem arises when the operation may take an arbitrarily long time to complete: an obvious example is a recv which may block until data has been received from the peer system. The default behavior within the Berkeley sockets model is for a socket to operate in a blocking mode unless the programmer explicitly requests that operations be treated as non-blocking.

Note  It is strongly recommended that programmers use the nonblocking (asynchronous) operations if at all possible, as they work significantly better within the nonpreemptive Windows environment. Use blocking operations only if absolutely necessary, and carefully read and understand this section if you must use blocking operations.

Even on a blocking socket, some operations (e.g. bind, getsockopt, getpeername) can be completed immediately. For such operations there is no difference between blocking and non-blocking operation. Other operations (e.g. recv) may be completed immediately or may take an arbitrary time to complete, depending on various transport conditions. When applied to a blocking socket, these operations are referred to as blocking operations. All routines which can block are listed with an asterisk in the tables.

Within a Windows Sockets implementation, a blocking operation which cannot be completed immediately is handled as follows. The DLL initiates the operation, and then enters a loop in which it dispatches any Windows messages (yielding the processor to another thread if necessary) and then checks for the completion of the Windows Sockets function. If the function has completed, or if WSACancelBlockingCall has been invoked, the blocking function completes with an appropriate result. Refer to WSASetBlockingHook for a complete description of this mechanism, including pseudocode for the various functions.

If a Windows message is received for a process for which a blocking operation is in progress, there is a risk that the application will attempt to issue another Windows Sockets call. Because of the difficulty of managing this condition safely, the Windows Sockets specification does not support such application behavior. Two functions are provided to assist the programmer in this situation. WSAIsBlocking may be called to determine whether or not a blocking Windows Sockets call is in progress. WSACancelBlockingCall may be called to cancel an in-progress blocking call, if any. Any other Windows Sockets function which is called in this situation will fail with the error WSAEINPROGRESS. It should be emphasized that this restriction applies to both blocking and non-blocking operations.

Although this mechanism is sufficient for simple applications, it cannot support the complex message-dispatching requirements of more advanced applications (for example, those using the MDI model). For such applications, the Windows Sockets API includes the function WSASetBlockingHook, which allows the programmer to define a special routine which will be called instead of the default message dispatch routine described above.

The Windows Sockets DLL calls the blocking hook only if all of the following are true: the routine is one which is defined as being able to block, the specified socket is a blocking socket, and the request cannot be completed immediately. (A socket is set to blocking by default, but the IOCTL FIONBIO and WSAAsyncSelect both set a socket to nonblocking mode.) If an application uses only non-blocking sockets and uses the WSAAsyncSelect and/or the WSAAsyncGetXByY routines instead of select and the getXbyY routines, then the blocking hook will never be called and the application does not need to be concerned with the reentrancy issues the blocking hook can introduce.

If an application invokes an asynchronous or non-blocking operation which takes a pointer to a memory object (e.g. a buffer, or a global variable) as an argument, it is the responsibility of the application to ensure that the object is available to the Windows Sockets implementation throughout the operation. The application must not invoke any Windows function which might affect the mapping or addressability of the memory involved. In a multithreaded system, the application is also responsible for coordinating access to the object using appropriate synchronization mechanisms. A Windows Sockets implementation cannot, and will not, address these issues. The possible consequences of failing to observe these rules are beyond the scope of this specification.


Database Functions

The Windows Sockets specification defines the following "database" routines. As noted earlier, a Windows Sockets supplier may choose to implement these in a manner which does not depend on local database files. The pointer returned by certain database routines such as gethostbyname points to a structure which is allocated by the Windows Sockets library. The data which is pointed to is volatile and is good only until the next Windows Sockets API call from that thread. Additionally, the application must never attempt to modify this structure or to free any of its components. Only one copy of this structure is allocated for a thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

gethostbyaddr*	Retrieve the name(s) and address corresponding to a network address.
gethostbyname*	Retrieve the name(s) and address corresponding to a host name.
gethostname	Retrieve the name of the local host.
getprotobyname*	Retrieve the protocol name and number corresponding to a protocol name.
getprotobynumber*	Retrieve the protocol name and number corresponding to a protocol number.
getservbyname*	Retrieve the service name and port corresponding to a service name.
getservbyport*	Retrieve the service name and port corresponding to a port.
* The routine can block under some circumstances.


Microsoft Windows-specific Extension Functions

The Windows Sockets specification provides a number of extensions to the standard set of Berkeley Sockets routines. Principally, these extended APIs allow message-based, asynchronous access to network events. While use of this extended API set is not mandatory for socket-based programming (with the exception of WSAStartup and WSACleanup), it is recommended for conformance with the Microsoft Windows programming paradigm.

WSAAsyncGetHostByAddr	A set of functions which provide asynchronous
WSAAsyncGetHostByName	versions of the standard Berkeley
WSAAsyncGetProtoByName	getXbyY functions. For example, the
WSAAsyncGetProtoByNumber	WSAAsyncGetHostByName function provides an
WSAAsyncGetServByName	asynchronous message based implementation of
WSAAsyncGetServByPort	the standard Berkeley gethostbyname function.
WSAAsyncSelect	Perform asynchronous version of select
WSACancelAsyncRequest	Cancel an outstanding instance of a WSAAsyncGetXByY function.
WSACancelBlockingCall	Cancel an outstanding "blocking" API call
WSACleanup	Sign off from the underlying Windows Sockets DLL.
WSAGetLastError	Obtain details of last Windows Sockets API error
WSAIsBlocking	Determine if the underlying Windows Sockets DLL is already blocking an existing call for this thread
WSASetBlockingHook	"Hook" the blocking method used by the underlying Windows Sockets implementation
WSASetLastError	Set the error to be returned by a subsequent WSAGetLastError
WSAStartup	Initialize the underlying Windows Sockets DLL.
WSAUnhookBlockingHook	Restore the original blocking function


Asynchronous select() Mechanism
Asynchronous select Mechanism

The WSAAsyncSelect API allows an application to register an interest in one or many network events. This API is provided to supersede the need to do polled network I/O. Any situation in which select or non-blocking I/O routines (such as send and recv) are either already used or are being considered is usually a candidate for the WSAAsyncSelect API. When declaring interest in such condition(s), you supply a window handle to be used for notification. The corresponding window then receives message-based notification of the conditions in which you declared an interest.

WSAAsyncSelect allows interest to be declared in the following conditions for a particular socket:

•	Socket readiness for reading

•	Socket readiness for writing

•	Out-of-band data ready for reading

•	Socket readiness for accepting incoming connection

•	Completion of non-blocking connect

•	Connection closure


Asynchronous Support Routines

The asynchronous "database" functions allow applications to request information in an asynchronous manner. Some network implementations and/or configurations perform network based operations to resolve such requests. The WSAAsyncGetXByY functions allow application developers to request services which would otherwise block the operation of the whole Windows environment if the standard Berkeley function were used. The WSACancelAsyncRequest function allows an application to cancel any outstanding asynchronous request.


Hooking Blocking Methods

As noted in section 3.1.1 above, Windows Sockets implements blocking operations in such a way that Windows message processing can continue, which may result in the application which issued the call receiving a Windows message. In certain situations an application may want to influence or change the way in which this pseudo-blocking process is implemented. The WSASetBlockingHook provides the ability to substitute a named routine which the Windows Sockets implementation is to use when relinquishing the processor during a "blocking" operation.


Error Handling

For compatibility with thread-based environments, details of API errors are obtained through the WSAGetLastError API. Although the accepted "Berkeley-Style" mechanism for obtaining socket-based network errors is via "errno", this mechanism cannot guarantee the integrity of an error ID in a multi-threaded environment. WSAGetLastError allows you to retrieve an error code on a per thread basis.

WSAGetLastError returns error codes which avoid conflict with standard Microsoft C error codes. Certain error codes returned by certain Windows Sockets routines fall into the standard range of error codes as defined by Microsoft C. If you are NOT using an application development environment which defines error codes consistent with Microsoft C, you are advised to use the Windows Sockets error codes prefixed by "WSA" to ensure accurate error code detection.

Note that this specification defines a recommended set of error codes, and lists the possible errors which may be returned as a result of each function. It may be the case in some implementations that other Windows Sockets error codes will be returned in addition to those listed, and applications should be prepared to handle errors other than those enumerated under each API description. However a Windows Sockets implementation must not return any value which is not enumerated in the table of legal Windows Sockets errors given in Error Codes.


Accessing a Windows Sockets DLL from an Intermediate DLL

A Windows Sockets DLL may be accessed both directly from an application and through an "intermediate" DLL. An example of such an intermediate DLL would be a virtual network API layer that supports generalized network functionality for applications and uses Windows Sockets. Such a DLL could be used by several applications simultaneously, and the DLL must take special precautions with respect to the WSAStartup and WSACleanup calls to ensure that these routines are called in the context of each task that will make Windows Sockets calls. This is because the Windows Sockets DLL will need a call to WSAStartup for each task in order to set up task-specific data structures, and a call to WSACleanup to free any resources allocated for the task.

There are (at least) two ways to accomplish this. The simplest method is for the intermediate DLL to have calls similar to WSAStartup and WSACleanup that applications call as appropriate. The DLL would then call WSAStartup or WSACleanup from within these routines. Another mechanism is for the intermediate DLL to build a table of task handles, which are obtained from the GetCurrentTask Windows API, and at each entry point into the intermediate DLL check whether WSAStartup has been called for the current task, then call WSAStartup if necessary.

If a DLL makes a blocking call and does not install its own blocking hook, then the DLL author must be aware that control may be returned to the application either by an application-installed blocking hook or by the default blocking hook. Thus, it is possible that the application will cancel the DLL's blocking operation via WSACancelBlockingCall. If this occurs, the DLL's blocking operation will fail with the error code WSAEINTR, and the DLL must return control to the calling task as quickly as possible, as the used has likely pressed a cancel or close button and the task has requested control of the CPU. It is recommended that DLLs which make blocking calls install their own blocking hooks with WSASetBlockingHook to prevent unforeseen interactions between the application and the DLL.

Note that this is not necessary for DLLs in Windows NT because of its different process and DLL structure. Under Windows NT, the intermediate DLL could simply call WSAStartup in its DLL initialization routine, which is called whenever a new process which uses the DLL starts.


Internal use of Messages by Windows Sockets Implementations

To implement Windows Sockets purely as a DLL, it may be necessary for the DLL to post messages internally for communication and timing. This is perfectly legal; however, a Windows Sockets DLL must not post messages to a window handle opened by a client application except for those messages requested by the application. A Windows Sockets DLL that needs to use messages for its own purposes must open a hidden window and post any necessary messages to the handle for that window.


Private API Interfaces

The winsock.def file in Appendix B.7 lists the ordinals defined for the Windows Sockets APIs. In addition to the ordinal values listed, all ordinals 999 and below are reserved for future Windows Sockets use. It may be convenient for a Windows Sockets implementation to export additional, private interfaces from the Windows Sockets DLL. This is perfectly acceptable, as long as the ordinals for these exports are above 1000. Note that any application that uses a particular Windows Sockets DLL's private APIs will most likely not work on any other vendor's Windows Sockets implementation. Only the APIs defined in this document are guaranteed to be present in every Windows Sockets implementation.

If an application uses private interfaces of a particular vendor's Windows Sockets DLL, it is recommended that the DLL not be statically linked with the application but rather dynamically loaded with the Windows routines LoadLibrary and GetProcAddress. This allows the application to give an informative error message if it is run on a system with a Windows Sockets DLL that does not support the same set of extended functionality.


Socket Library Reference

Socket Routines

This chapter presents the socket library routines in alphabetical order, and describes each routine in detail.

In each routine it is indicated that the header file winsock.h must be included. Appendix A.2 lists the Berkeley-compatible header files which are supported. These are provided for compatibility purposes only, and each of them will simply include winsock.h. The Windows header file windows.h is also needed, but winsock.h will include it if necessary.


accept()
accept

Description

Accept a connection on a socket.

 	#include <winsock.h>

 	SOCKET PASCAL FAR accept ( SOCKET s, struct sockaddr FAR * addr,

int FAR * addrlen );

s

A descriptor identifying a socket which is listening for connections after a listen.

addr

An optional pointer to a buffer which receives the address of the connecting entity, as known to the communications layer. The exact format of the addr argument is determined by the address family established when the socket was created.

addrlen

An optional pointer to an integer which contains the length of the address addr.

Remarks

This routine extracts the first connection on the queue of pending connections on s, creates a new socket with the same properties as s and returns a handle to the new socket. If no pending connections are present on the queue, and the socket is not marked as non-blocking, accept blocks the caller until a connection is present. If the socket is marked non-blocking and no pending connections are present on the queue, accept returns an error as described below. The accepted socket may not be used to accept more connections. The original socket remains open.

The argument addr is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr; on return it will contain the actual length (in bytes) of the address returned. This call is used with connection-based socket types such as SOCK_STREAM. If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.

Return Value

If no error occurs, accept returns a value of type SOCKET which is a descriptor for the accepted packet. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code may be retrieved by calling WSAGetLastError.

The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the actual length in bytes of the address returned.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	The addrlen argument is too small (less than the sizeof a struct sockaddr).
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
WSAEINVAL	listen was not invoked prior to accept.
WSAEMFILE	The queue is empty upon entry to accept and there are no descriptors available.
WSAENOBUFS	No buffer space is available.
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	The referenced socket is not a type that supports connection-oriented service.
WSAEWOULDBLOCK	The socket is marked as non-blocking and no connections are present to be accepted.
See Also

bind, connect, listen, select, socket, WSAAsyncSelect


bind()
bind

Description

Associate a local address with a socket.

 	#include <winsock.h>

 	int PASCAL FAR bind ( SOCKET s, const struct sockaddr FAR * name, int namelen );

s

A descriptor identifying an unbound socket.

name

The address to assign to the socket. The sockaddr structure is defined as follows:

struct sockaddr {

u_short	sa_family;

char	sa_data[14];

};

namelen

The length of the name.

Remarks

This routine is used on an unconnected datagram or stream socket, before subsequent connects or listens. When a socket is created with socket, it exists in a name space (address family), but it has no name assigned. bind establishes the local association (host address/port number) of the socket by assigning a local name to an unnamed socket.

In the Internet address family, a name consists of several components. For SOCK_DGRAM and SOCK_STREAM, the name consists of three parts: a host address, the protocol number (set implicitly to UDP or TCP, respectively), and a port number which identifies the application. If an application does not care what address is assigned to it, it may specify an Internet address equal to INADDR_ANY, a port equal to 0, or both. If the Internet address is equal to INADDR_ANY, any appropriate network interface will be used; this simplifies application programming in the presence of multi-homed hosts. If the port is specified as 0, the Windows Sockets implementation will assign a unique port to the application with a value between 1024 and 5000. The application may use getsockname after bind to learn the address that has been assigned to it, but note that getsockname will not necessarily fill in the Internet address until the socket is connected, since several Internet addresses may be valid if the host is multi-homed.

If an application desires to bind to an arbitrary port outside of the range 1024 to 5000, such as the case of rsh which must bind to any reserved port, code similar to the following may be used:

 SOCKADDR_IN sin;

 SOCKET s;

 u_short alport = IPPORT_RESERVED;

 sin.sin_family = AF_INET;

 sin.sin_addr.s_addr = 0;

 for (;;) {

 sin.sin_port = htons(alport);

 if (bind(s, (LPSOCKADDR)&sin, sizeof (sin)) == 0) {

  /* it worked */

 }

 if ( GetLastError != WSAEADDRINUSE) {

  /* fail */

 }

 alport--;

 if (alport == IPPORT_RESERVED/2 ) {

  /* fail--all unassigned reserved ports are */

  /* in use. */

 }

 }

Return Value

If no error occurs, bind returns 0. Otherwise, it returns SOCKET_ERROR, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEADDRINUSE	The specified address is already in use. (See the SO_REUSEADDR socket option under setsockopt.)
WSAEFAULT	The namelen argument is too small (less than the size of a struct sockaddr).
WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
WSAEAFNOSUPPORT	The specified address family is not supported by this protocol.
WSAEINVAL	The socket is already bound to an address.
WSAENOBUFS	Not enough buffers available, too many connections.
WSAENOTSOCK	The descriptor is not a socket.
See Also

connect, listen, getsockname, setsockopt, socket, WSACancelBlockingCall.


closesocket()
closesocket

Description

Close a socket.

 	#include <winsock.h>

 	int PASCAL FAR closesocket ( SOCKET s );

s

A descriptor identifying a socket.

Remarks

This function closes a socket. More precisely, it releases the socket descriptor s, so that further references to s will fail with the error WSAENOTSOCK. If this is the last reference to the underlying socket, the associated naming information and queued data are discarded.

The semantics of closesocket are affected by the socket options SO_LINGER and SO_DONTLINGER as follows:

Option	Interval	Type of close	Wait for close?
SO_DONTLINGER	Don't care	Graceful	No
SO_LINGER	Zero	Hard	No
SO_LINGER	Non-zero	Graceful	Yes
If SO_LINGER is set (i.e. the l_onoff field of the linger structure is non-zero; see sections , and ) with a zero timeout interval (l_linger is zero), closesocket is not blocked even if queued data has not yet been sent or acknowledged. This is called a "hard" or "abortive" close, because the socket's virtual circuit is reset immediately, and any unsent data is lost. Any recv call on the remote side of the circuit will fail with WSAECONNRESET.

If SO_LINGER is set with a non-zero timeout interval, the closesocket call blocks until the remaining data has been sent or until the timeout expires. This is called a graceful disconnect. Note that if the socket is set to non-blocking and SO_LINGER is set to a non-zero timeout, the call to closesocket will fail with an error of WSAEWOULDBLOCK.

If SO_DONTLINGER is set on a stream socket (i.e. the l_onoff field of the linger structure is zero; see sections , and ), the closesocket call will return immediately. However, any data queued for transmission will be sent if possible before the underlying socket is closed. This is also called a graceful disconnect. Note that in this case the Windows Sockets implementation may not release the socket and other resources for an arbitrary period, which may affect applications which expect to use all available sockets.

Return Value

If no error occurs, closesocket returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOTSOCK	The descriptor is not a socket.
WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEWOULDBLOCK	The socket is marked as nonblocking and SO_LINGER is set to a nonzero timeout value.
See Also

accept, socket, ioctlsocket, setsockopt, WSAAsyncSelect


connect()
connect

Description

Establish a connection to a peer.

 	#include <winsock.h>

 	int PASCAL FAR connect ( SOCKET s, const struct sockaddr FAR * name,

int namelen );

s

A descriptor identifying an unconnected socket.

name

The name of the peer to which the socket is to be connected.

namelen

The length of the name.

Remarks

This function is used to create a connection to the specified foreign association. The parameter s specifies an unconnected datagram or stream socket If the socket is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound. Note that if the address field of the name structure is all zeroes, connect will return the error WSAEADDRNOTAVAIL.

For stream sockets (type SOCK_STREAM), an active connection is initiated to the foreign host using name (an address in the name space of the socket). When the socket call completes successfully, the socket is ready to send/receive data.

For a datagram socket (type SOCK_DGRAM), a default destination is set, which will be used on subsequent send and recv calls.

Return Value

If no error occurs, connect returns 0. Otherwise, it returns SOCKET_ERROR, and a specific error code may be retrieved by calling WSAGetLastError.

On a blocking socket, the return value indicates success or failure of the connection attempt.

On a non-blocking socket, if the return value is SOCKET_ERROR an application should call WSAGetLastError. If this indicates an error code of WSAEWOULDBLOCK, then your application can either:

1.	Use select to determine the completion of the connection request by checking if the socket is writeable, or

2.	If your application is using the message-based WSAAsyncSelect to indicate interest in connection events, then your application will receive an FD_CONNECT message when the connect operation is complete.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEADDRINUSE	The specified address is already in use.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
WSAEADDRNOTAVAIL	The specified address is not available from the local machine.
WSAEAFNOSUPPORT	Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED	The attempt to connect was forcefully rejected.
WSAEDESTADDREQ	A destination address is required.
WSAEFAULT	The namelen argument is incorrect.
WSAEINVAL	The socket is not already bound to an address.
WSAEISCONN	The socket is already connected.
WSAEMFILE	No more file descriptors are available.
WSAENETUNREACH	The network can't be reached from this host at this time.
WSAENOBUFS	No buffer space is available. The socket cannot be connected.
WSAENOTSOCK	The descriptor is not a socket.
WSAETIMEDOUT	Attempt to connect timed out without establishing a connection
WSAEWOULDBLOCK	The socket is marked as non-blocking and the connection cannot be completed immediately. It is possible to select the socket while it is connecting by selecting it for writing.
See Also

accept, bind, getsockname, socket, select and WSAAsyncSelect.


getpeername()
getpeername

Description

Get the address of the peer to which a socket is connected.

 	#include <winsock.h>

 	int PASCAL FAR getpeername ( SOCKET s, struct sockaddr FAR * name, int FAR * namelen );

s

A descriptor identifying a connected socket.

name

The structure which is to receive the name of the peer.

namelen

A pointer to the size of the name structure.

Remarks

getpeername retrieves the name of the peer connected to the socket s and stores it in the struct sockaddr identified by name. It is used on a connected datagram or stream socket.

On return, the namelen argument contains the actual size of the name returned in bytes.

Return Value

If no error occurs, getpeername returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	The namelen argument is not large enough.
WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
WSAENOTCONN	The socket is not connected.
WSAENOTSOCK	The descriptor is not a socket.
See Also

bind, socket, getsockname


getsockname()
getsockname

Description

Get the local name for a socket.

 	#include <winsock.h>

 	int PASCAL FAR getsockname ( SOCKET s, struct sockaddr FAR * name,

int FAR * namelen );

s

A descriptor identifying a bound socket.

name

Receives the address (name) of the socket.

namelen

The size of the name buffer.

Remarks

getsockname retrieves the current name for the specified socket descriptor in name. It is used on a bound and/or connected socket specified by the s parameter. The local association is returned. This call is especially useful when a connect call has been made without doing a bind first; this call provides the only means by which you can determine the local association which has been set by the system.

On return, the namelen argument contains the actual size of the name returned in bytes.

If a socket was bound to INADDR_ANY, indicating that any of the host's IP addresses should be used for the socket, getsockname will not necessarily return information about the host IP address, unless the socket has been connected with connect or accept. A Windows Sockets application must not assume that the IP address will be changed from INADDR_ANY unless the socket is connected. This is because for a multi-homed host the IP address that will be used for the socket is unknown unless the socket is connected.

Return Value

If no error occurs, getsockname returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	The namelen argument is not large enough.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOTSOCK	The descriptor is not a socket.
WSAEINVAL	The socket has not been bound to an address with bind.
See Also

bind, socket, getpeername


getsockopt()
getsockopt

Description

Retrieve a socket option.

 	#include <winsock.h>

 	int PASCAL FAR getsockopt ( SOCKET s, int level, int optname,

char FAR * optval, int FAR * optlen );

s

A descriptor identifying a socket.

level

The level at which the option is defined; the only supported levels are SOL_SOCKET and IPPROTO_TCP.

optname

The socket option for which the value is to be retrieved.

optval

A pointer to the buffer in which the value for the requested option is to be returned.

optlen

A pointer to the size of the optval buffer.

Remarks

getsockopt retrieves the current value for a socket option associated with a socket of any type, in any state, and stores the result in optval. Options may exist at multiple protocol levels, but they are always present at the uppermost "socket" level. Options affect socket operations, such as whether an operation blocks or not, the routing of packets, out-of-band data transfer, etc.

The value associated with the selected option is returned in the buffer optval. The integer pointed to by optlen should originally contain the size of this buffer; on return, it will be set to the size of the value returned. For SO_LINGER, this will be the size of a struct linger; for all other options it will be the size of an integer.

If the option was never set with setsockopt, then getsockopt returns the default value for the option.

The following options are supported for getsockopt. The Type identifies the type of data addressed by optval. The TCP_NODELAY option uses level IPPROTO_TCP; all other options use level SOL_SOCKET.

Value	Type	Meaning
SO_ACCEPTCONN	BOOL	Socket is listening.
SO_BROADCAST	BOOL	Socket is configured for the transmission of broadcast messages.
SO_DEBUG	BOOL	Debugging is enabled.
SO_DONTLINGER	BOOL	If true, the SO_LINGER option is disabled.
SO_DONTROUTE	BOOL	Routing is disabled.
SO_ERROR	int	Retrieve error status and clear.
SO_KEEPALIVE	BOOL	Keepalives are being sent.
SO_LINGER	struct linger FAR *	Returns the current linger options.
SO_OOBINLINE	BOOL	Out-of-band data is being received in the normal data stream.
SO_RCVBUF	int	Buffer size for receives
SO_REUSEADDR	BOOL	The socket may be bound to an address which is already in use.
SO_SNDBUF	int	Buffer size for sends
SO_TYPE	int	The type of the socket (e.g. SOCK_STREAM).
TCP_NODELAY	BOOL	Disables the Nagle algorithm for send coalescing.
BSD options not supported for getsockopt are:

Value	Type	Meaning
SO_RCVLOWAT	int	Receive low water mark
SO_RCVTIMEO	int	Receive timeout
SO_SNDLOWAT	int	Send low water mark
SO_SNDTIMEO	int	Send timeout
IP_OPTIONS		Get options in IP header.
TCP_MAXSEG	int	Get TCP maximum segment size.
Calling getsockopt with an unsupported option will result in an error code of WSAENOPROTOOPT being returned from WSAGetLastError.

Return Value

If no error occurs, getsockopt returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	The optlen argument was invalid.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOPROTOOPT	The option is unknown or unsupported. In particular, SO_BROADCAST is not supported on sockets of type SOCK_STREAM, while SO_ACCEPTCONN, SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER and SO_OOBINLINE are not supported on sockets of type SOCK_DGRAM.
WSAENOTSOCK	The descriptor is not a socket.
See Also

setsockopt, WSAAsyncSelect, socket


htonl()
htonl

Description

Convert a u_long from host to network byte order.

 	#include <winsock.h>

 	u_long PASCAL FAR htonl ( u_long hostlong );

hostlong

A 32-bit number in host byte order.

Remarks

This routine takes a 32-bit number in host byte order and returns a 32-bit number in network byte order.

Return Value

htonl returns the value in network byte order.

See Also

htons, ntohl, ntohs


htons()
htons

Description

Convert a u_short from host to network byte order.

 	#include <winsock.h>

 	u_short PASCAL FAR htons ( u_short hostshort );

hostshort

A 16-bit number in host byte order.

Remarks

This routine takes a 16-bit number in host byte order and returns a 16-bit number in network byte order.

Return Value

htons returns the value in network byte order.

See Also

htonl, ntohl, ntohs


inet_addr()
inet_addr

Description

Convert a string containing a dotted address into an in_addr.

 	#include <winsock.h>

unsigned long PASCAL FAR inet_addr ( const char FAR * cp );

cp

A character string representing a number expressed in the Internet standard "." notation.

Remarks

This function interprets the character string specified by the cp parameter. This string represents a numeric Internet address expressed in the Internet standard "." notation. The value returned is a number suitable for use as an Internet address. All Internet addresses are returned in network order (bytes ordered from left to right).

Internet Addresses

Values specified using the "." notation take one of the following forms:

a.b.c.d	a.b.c	a.b	a

When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address. Note that when an Internet address is viewed as a 32-bit integer quantity on the Intel architecture, the bytes referred to above appear as "d.c.b.a". That is, the bytes on an Intel processor are ordered from right to left.

Note: The following notations are only used by Berkeley, and nowhere else on the Internet. In the interests of compatibility with their software, they are supported as specified.

When a three part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right most two bytes of the network address. This makes the three part address format convenient for specifying Class B network addresses as "128.net.host".

When a two part address is specified, the last part is interpreted as a 24-bit quantity and placed in the right most three bytes of the network address. This makes the two part address format convenient for specifying Class A network addresses as "net.host".

When only one part is given, the value is stored directly in the network address without any byte rearrangement.

Return Value

If no error occurs, inet_addr returns an unsigned long containing a suitable binary representation of the Internet address given. If the passed-in string does not contain a legitimate Internet address, for example if a portion of an "a.b.c.d" address exceeds 255, inet_addr returns the value INADDR_NONE.

See Also

inet_ntoa


inet_ntoa()
inet_ntoa

Description

Convert a network address into a string in dotted format.

 	#include <winsock.h>

 	char FAR * PASCAL FAR inet_ntoa ( struct in_addr in );

in

A structure which represents an Internet host address.

Remarks

This function takes an Internet address structure specified by the in parameter. It returns an ASCII string representing the address in "." notation as "a.b.c.d". Note that the string returned by inet_ntoa resides in memory which is allocated by the Windows Sockets implementation. The application should not make any assumptions about the way in which the memory is allocated. The data is guaranteed to be valid until the next Windows Sockets API call within the same thread, but no longer.

Return Value

If no error occurs, inet_ntoa returns a char pointer to a static buffer containing the text address in standard "." notation. Otherwise, it returns NULL. The data should be copied before another Windows Sockets call is made.

See Also

inet_addr


ioctlsocket()
ioctlsocket

Description

Control the mode of a socket.

 	#include <winsock.h>

 	int PASCAL FAR ioctlsocket ( SOCKET s, long cmd, u_long FAR * argp );

s

A descriptor identifying a socket.

cmd

The command to perform on the socket s.

argp

A pointer to a parameter for cmd.

Remarks

This routine may be used on any socket in any state. It is used to get or retrieve operating parameters associated with the socket, independent of the protocol and communications subsystem. The following commands are supported:

Command	Semantics
FIONBIO	Enable or disable non-blocking mode on the socket s. argp points at an unsigned long, which is non-zero if non-blocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking mode (i.e. non-blocking mode is disabled). This is consistent with BSD sockets.
	The WSAAsyncSelect routine automatically sets a socket to nonblocking mode. If WSAAsyncSelect has been issued on a socket, then any attempt to use ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling WSAAsyncSelect with the lEvent parameter equal to 0.
FIONREAD	Determine the amount of data which can be read atomically from socket s. argp points at an unsigned long in which ioctlsocket stores the result. If s is of type SOCK_STREAM, FIONREAD returns the total amount of data which may be read in a single recv; this is normally the same as the total amount of data queued on the socket. If s is of type SOCK_DGRAM, FIONREAD returns the size of the first datagram queued on the socket.
SIOCATMARK	Determine whether or not all out-of-band data has been read. This applies only to a socket of type SOCK_STREAM which has been configured for in-line reception of any out-of-band data (SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation returns TRUE. Otherwise it returns FALSE, and the next recv or recvfrom performed on the socket will retrieve some or all of the data preceding the "mark"; the application should use the SIOCATMARK operation to determine whether any remains. If there is any normal data preceding the "urgent" (out of band) data, it will be received in order. (Note that a recv or recvfrom will never mix out-of-band and normal data in the same call.) argp points at a BOOL in which ioctlsocket stores the result.
Compatibility

This function is a subset of ioctl as used in Berkeley sockets. In particular, there is no command which is equivalent to FIOASYNC, while SIOCATMARK is the only socket-level command which is supported.

Return Value

Upon successful completion, the ioctlsocket returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	cmd is not a valid command, or argp is not an acceptable parameter for cmd, or the command is not applicable to the type of socket supplied
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOTSOCK	The descriptor s is not a socket.
See Also

socket, setsockopt, getsockopt, WSAAsyncSelect


listen()
listen

Description

Establish a socket to listen for incoming connection.

 	#include <winsock.h>

 	int PASCAL FAR listen ( SOCKET s, int backlog );

s

A descriptor identifying a bound, unconnected socket.

backlog

The maximum length to which the queue of pending connections may grow.

Remarks

To accept connections, a socket is first created with socket, a backlog for incoming connections is specified with listen, and then the connections are accepted with accept. listen applies only to sockets that support connections, i.e. those of type SOCK_STREAM. The socket s is put into "passive" mode where incoming connections are acknowledged and queued pending acceptance by the process.

This function is typically used by servers that could have more than one connection request at a time: if a connection request arrives with the queue full, the client will receive an error with an indication of WSAECONNREFUSED.

listen attempts to continue to function rationally when there are no available descriptors. It will accept connections until the queue is emptied. If descriptors become available, a later call to listen or accept will re-fill the queue to the current or most recent "backlog", if possible, and resume listening for incoming connections.

Compatibility	backlog is currently limited (silently) to 5. As in 4.3BSD, illegal values (less than 1 or greater than 5) are replaced by the nearest legal value.

Return Value

If no error occurs, listen returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEADDRINUSE	An attempt has been made to listen on an address in use.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINVAL	The socket has not been bound with bind or is already connected.
WSAEISCONN	The socket is already connected.
WSAEMFILE	No more file descriptors are available.
WSAENOBUFS	No buffer space is available.
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	The referenced socket is not of a type that supports the listen operation.
See Also

accept, connect, socket


ntohl()
ntohl

Description

Convert a u_long from network to host byte order.

 	#include <winsock.h>

 	u_long PASCAL FAR ntohl ( u_long netlong );

netlong

A 32-bit number in network byte order.

Remarks

This routine takes a 32-bit number in network byte order and returns a 32-bit number in host byte order.

Return Value

ntohl returns the value in host byte order.

See Also

htonl, htons, ntohs


ntohs()
ntohs

Description

Convert a u_short from network to host byte order.

 	#include <winsock.h>

 	u_short PASCAL FAR ntohs ( u_short netshort );

netshort

A 16-bit number in network byte order.

Remarks

This routine takes a 16-bit number in network byte order and returns a 16-bit number in host byte order.

Return Value

ntohs returns the value in host byte order.

See Also

htonl, htons, ntohl


recv()
recv

Description

Receive data from a socket.

 	#include <winsock.h>

 	int PASCAL FAR recv ( SOCKET s, char FAR * buf, int len, int flags );

s

A descriptor identifying a connected socket.

buf

A buffer for the incoming data.

len

The length of buf.

flags

Specifies the way in which the call is made.

Remarks

This function is used on connected datagram or stream sockets specified by the s parameter and is used to read incoming data.

For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer supplied is returned. If the socket has been configured for in-line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application may use the ioctlsocket SIOCATMARK to determine whether any more out-of-band data remains to be read.

For datagram sockets, data is extracted from the first enqueued datagram, up to the size of the buffer supplied. If the datagram is larger than the buffer supplied, the buffer is filled with the first part of the datagram, the excess data is lost, and recv returns the error WSAEMSGSIZE.

If no incoming data is available at the socket, the recv call waits for data to arrive unless the socket is non-blocking. In this case a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select or WSAAsyncSelect calls may be used to determine when more data arrives.

If the socket is of type SOCK_STREAM and the remote side has shut down the connection gracefully, a recv will complete immediately with 0 bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.

Flags may be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing any of the following values:

Value	Meaning
MSG_PEEK	Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
MSG_OOB	Process out-of-band data (See section for a discussion of this topic.)
Return Value

If no error occurs, recv returns the number of bytes received. If the connection has been closed, it returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOTCONN	The socket is not connected.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN	The socket has been shutdown; it is not possible to recv on a socket after shutdown has been invoked with how set to 0 or 2.
WSAEWOULDBLOCK	The socket is marked as non-blocking and the receive operation would block.
WSAEMSGSIZE	The datagram was too large to fit into the specified buffer and was truncated.
WSAEINVAL	The socket has not been bound with bind.
WSAECONNABORTED	The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET	The virtual circuit was reset by the remote side.
See Also

recvfrom, ,recv, send, select, WSAAsyncSelect, socket


recvfrom()
recvfrom

Description

Receive a datagram and store the source address.

 	#include <winsock.h>

 	int PASCAL FAR recvfrom ( SOCKET s, char FAR * buf, int len, int flags,

struct sockaddr FAR * from, int FAR * fromlen );

s

A descriptor identifying a bound socket.

buf

A buffer for the incoming data.

len

The length of buf.

flags

Specifies the way in which the call is made.

from

An optional pointer to a buffer which will hold the source address upon return.

fromlen

An optional pointer to the size of the from buffer.

Remarks

This function is used to read incoming data on a (possibly connected) socket and capture the address from which the data was sent.

For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer supplied is returned. If the socket has been configured for in-line reception of out-of-band data (socket option SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application may use the ioctlsocket SIOCATMARK to determine whether any more out-of-band data remains to be read. The from and fromlen parameters are ignored for SOCK_STREAM sockets.

For datagram sockets, data is extracted from the first enqueued datagram, up to the size of the buffer supplied. If the datagram is larger than the buffer supplied, the buffer is filled with the first part of the message, the excess data is lost, and recvfrom returns the error code WSAEMSGSIZE.

If from is non-zero, and the socket is of type SOCK_DGRAM, the network address of the peer which sent the data is copied to the corresponding struct sockaddr. The value pointed to by fromlen is initialized to the size of this structure, and is modified on return to indicate the actual size of the address stored there.

If no incoming data is available at the socket, the recvfrom call waits for data to arrive unless the socket is non-blocking. In this case a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select or WSAAsyncSelect calls may be used to determine when more data arrives.

If the socket is of type SOCK_STREAM and the remote side has shut down the connection gracefully, a recvfrom will complete immediately with 0 bytes received. If the connection has been reset recv will fail with the error WSAECONNRESET.

Flags may be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing any of the following values:

Value	Meaning
MSG_PEEK	Peek at the incoming data. The data is copied into the buffer but is not removed from the input queue.
MSG_OOB	Process out-of-band data (See section for a discussion of this topic.)
Return Value

If no error occurs, recvfrom returns the number of bytes received. If the connection has been closed, it returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	The fromlen argument was invalid: the from buffer was too small to accommodate the peer address.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINVAL	The socket has not been bound with bind.
WSAENOTCONN	The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN	The socket has been shutdown; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to 0 or 2.
WSAEWOULDBLOCK	The socket is marked as non-blocking and the recvfrom operation would block.
WSAEMSGSIZE	The datagram was too large to fit into the specified buffer and was truncated.
WSAECONNABORTED	The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET	The virtual circuit was reset by the remote side.
See Also

recv, send, socket, WSAAsyncSelect


select()
select

Description

Determine the status of one or more sockets, waiting if necessary.

 	#include <winsock.h>

 	int PASCAL FAR select ( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout );

nfds

This argument is ignored and included only for the sake of compatibility.

readfds

An optional pointer to a set of sockets to be checked for readability.

writefds

An optional pointer to a set of sockets to be checked for writability

exceptfds

An optional pointer to a set of sockets to be checked for errors.

timeout

The maximum time for select to wait, or NULL for blocking operation.

Remarks

This function is used to determine the status of one or more sockets. For each socket, the caller may request information on read, write or error status. The set of sockets for which a given status is requested is indicated by an fd_set structure. Upon return, the structure is updated to reflect the subset of these sockets which meet the specified condition, and select returns the number of sockets meeting the conditions. A set of macros is provided for manipulating an fd_set. These macros are compatible with those used in the Berkeley software, but the underlying representation is completely different.

The parameter readfds identifies those sockets which are to be checked for readability. If the socket is currently listening, it will be marked as readable if an incoming connection request has been received, so that an accept is guaranteed to complete without blocking. For other sockets, readability means that queued data is available for reading or, for sockets of type SOCK_STREAM, that the virtual socket corresponding to the socket has been closed, so that a recv or recvfrom is guaranteed to complete without blocking. If the virtual circuit was closed gracefully, then a recv will return immediately with 0 bytes read; if the virtual circuit was reset, then a recv will complete immediately with the error code WSAECONNRESET. The presence of out-of-band data will be checked if the socket option SO_OOBINLINE has been enabled (see setsockopt).

The parameter writefds identifies those sockets which are to be checked for writability. If a socket is connecting (non-blocking), writability means that the connection establishment successfully completed. If the socket is not in the process of connecting, writability means that a send or sendto will complete without blocking. [It is not specified how long this guarantee can be assumed to be valid, particularly in a multithreaded environment.]

The parameter exceptfds identifies those sockets which are to be checked for the presence of out-of-band data or any exceptional error conditions. Note that out-of-band data will only be reported in this way if the option SO_OOBINLINE is FALSE. For a SOCK_STREAM, the breaking of the connection by the peer or due to KEEPALIVE failure will be indicated as an exception. This specification does not define which other errors will be included. If a socket is connecting (non-blocking), failure of the connect attempt is indicated in exceptfds.

Any of readfds, writefds, or exceptfds may be given as NULL if no descriptors are of interest.

Four macros are defined in the header file winsock.h for manipulating the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which may be modified by #defining FD_SETSIZE to another value before #including winsock.h.) Internally, an fd_set is represented as an array of SOCKETs; the last valid entry is followed by an element set to INVALID_SOCKET. The macros are:

FD_CLR(s, *set)	Removes the descriptor s from set.
FD_ISSET(s, *set)	Nonzero if s is a member of the set, zero otherwise.
FD_SET(s, *set)	Adds descriptor s to set.
FD_ZERO(*set)	Initializes the set to the NULL set.
The parameter timeout controls how long the select may take to complete. If timeout is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, timeout points to a struct timeval which specifies the maximum time that select should wait before returning. If the timeval is initialized to {0, 0}, select will return immediately; this is used to "poll" the state of the selected sockets. If this is the case, then the select call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, the blocking hook must not be called, and the Windows Sockets implementation must not yield.

Return Value

select returns the total number of descriptors which are ready and contained in the fd_set structures, 0 if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError may be used to retrieve a specific error code.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	The timeout value is not valid.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOTSOCK	One of the descriptor sets contains an entry which is not a socket.
See Also

WSAAsyncSelect, accept, connect, recv, recvfrom, send


send()
send

Description

Send data on a connected socket.

 	#include <winsock.h>

 	int PASCAL FAR send ( SOCKET s, const char FAR * buf, int len, int flags );

s

A descriptor identifying a connected socket.

buf

A buffer containing the data to be transmitted.

len

The length of the data in buf.

flags

Specifies the way in which the call is made.

Remarks

send is used on connected datagram or stream sockets and is used to write outgoing data on a socket. For datagram sockets, care must be taken not to exceed the maximum IP packet size of the underlying subnets, which is given by the iMaxUdpDg element in the WSAData structure returned by WSAStartup. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

Note that the successful completion of a send does not indicate that the data was successfully delivered.

If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in a non-blocking I/O mode. On non-blocking SOCK_STREAM sockets, the number of bytes written may be between 1 and the requested length, depending on buffer availability on both the local and foreign hosts. The select call may be used to determine when it is possible to send more data.

Flags may be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing any of the following values:

Value	Meaning
MSG_DONTROUTE	Specifies that the data should not be subject to routing. A Windows Sockets supplier may choose to ignore this flag; see also the discussion of the SO_DONTROUTE option.
MSG_OOB	Send out-of-band data (SOCK_STREAM only)
Return Value

If no error occurs, send returns the total number of characters sent. (Note that this may be less than the number indicated by len.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEACCES	The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEFAULT	The buf argument is not in a valid part of the user address space.
WSAENETRESET	The connection must be reset because the Windows Sockets implementation dropped it.
WSAENOBUFS	The Windows Sockets implementation reports a buffer deadlock.
WSAENOTCONN	The socket is not connected.
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN	The socket has been shutdown; it is not possible to send on a socket after shutdown has been invoked with how set to 1 or 2.
WSAEWOULDBLOCK	The socket is marked as non-blocking and the requested operation would block.
WSAEMSGSIZE	The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum supported by the Windows Sockets implementation.
WSAEINVAL	The socket has not been bound with bind.
WSAECONNABORTED	The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET	The virtual circuit was reset by the remote side.
See Also

recv, recvfrom, socket, sendto, WSAStartup


sendto()
sendto

Description

Send data to a specific destination.

 	#include <winsock.h>

 	int PASCAL FAR sendto ( SOCKET s, const char FAR * buf, int len, int flags,

const struct sockaddr FAR * to, int tolen );

s

A descriptor identifying a socket.

buf

A buffer containing the data to be transmitted.

len

The length of the data in buf.

flags

Specifies the way in which the call is made.

to

An optional pointer to the address of the target socket.

tolen

The size of the address in to.

Remarks

sendto is used on datagram or stream sockets and is used to write outgoing data on a socket. For datagram sockets, care must be taken not to exceed the maximum IP packet size of the underlying subnets, which is given by the iMaxUdpDg element in the WSAData structure returned by WSAStartup. If the data is too long to pass atomically through the underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.

Note that the successful completion of a sendto does not indicate that the data was successfully delivered.

sendto is normally used on a SOCK_DGRAM socket to send a datagram to a specific peer socket identified by the to parameter. On a SOCK_STREAM socket, the to and tolen parameters are ignored; in this case the sendto is equivalent to send.

To send a broadcast (on a SOCK_DGRAM only), the address in the to parameter should be constructed using the special IP address INADDR_BROADCAST (defined in winsock.h) together with the intended port number. It is generally inadvisable for a broadcast datagram to exceed the size at which fragmentation may occur, which implies that the data portion of the datagram (excluding headers) should not exceed 512 bytes.

If no buffer space is available within the transport system to hold the data to be transmitted, sendto will block unless the socket has been placed in a non-blocking I/O mode. On non-blocking SOCK_STREAM sockets, the number of bytes written may be between 1 and the requested length, depending on buffer availability on both the local and foreign hosts. The select call may be used to determine when it is possible to send more data.

Flags may be used to influence the behavior of the function invocation beyond the options specified for the associated socket. That is, the semantics of this function are determined by the socket options and the flags parameter. The latter is constructed by or-ing any of the following values:

Value	Meaning
MSG_DONTROUTE	Specifies that the data should not be subject to routing. A Windows Sockets supplier may choose to ignore this flag; see also the discussion of the SO_DONTROUTE option.
MSG_OOB	Send out-of-band data (SOCK_STREAM only).
Return Value

If no error occurs, sendto returns the total number of characters sent. (Note that this may be less than the number indicated by len.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEACCES	The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEFAULT	The buf or to parameters are not part of the user address space, or the to argument is too small (less than the sizeof a struct sockaddr).
WSAENETRESET	The connection must be reset because the Windows Sockets implementation dropped it.
WSAENOBUFS	The Windows Sockets implementation reports a buffer deadlock.
WSAENOTCONN	The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK	The descriptor is not a socket.
WSAEOPNOTSUPP	MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN	The socket has been shutdown; it is not possible to sendto on a socket after shutdown has been invoked with how set to 1 or 2.
WSAEWOULDBLOCK	The socket is marked as non-blocking and the requested operation would block.
WSAEMSGSIZE	The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum supported by the Windows Sockets implementation.
WSAECONNABORTED	The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET	The virtual circuit was reset by the remote side.
WSAEADDRNOTAVAIL	The specified address is not available from the local machine.
WSAEAFNOSUPPORT	Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ	A destination address is required.
WSAENETUNREACH	The network can't be reached from this host at this time.
See Also

recv, recvfrom, socket, send, WSAStartup


setsockopt()
setsockopt

Description

Set a socket option.

 	#include <winsock.h>

 	int PASCAL FAR setsockopt ( SOCKET s, int level, int optname,

const char FAR * optval, int optlen );

s

A descriptor identifying a socket.

level

The level at which the option is defined; the only supported levels are SOL_SOCKET and IPPROTO_TCP.

optname

The socket option for which the value is to be set.

optval

A pointer to the buffer in which the value for the requested option is supplied.

optlen

The size of the optval buffer.

Remarks

setsockopt sets the current value for a socket option associated with a socket of any type, in any state. Although options may exist at multiple protocol levels, this specification only defines options that exist at the uppermost "socket" level. Options affect socket operations, such as whether expedited data is received in the normal data stream, whether broadcast messages may be sent on the socket, etc.

There are two types of socket options: Boolean options that enable or disable a feature or behavior, and options which require an integer value or structure. To enable a Boolean option, optval points to a nonzero integer. To disable the option optval points to an integer equal to zero. optlen should be equal to sizeof(int) for Boolean options. For other options, optval points to the an integer or structure that contains the desired value for the option, and optlen is the length of the integer or structure.

SO_LINGER controls the action taken when unsent data is queued on a socket and a closesocket is performed. See closesocket for a description of the way in which the SO_LINGER settings affect the semantics of closesocket. The application sets the desired behavior by creating a struct linger (pointed to by the optval argument) with the following elements:

struct linger {

int	l_onoff;

int	l_linger;

}

To enable SO_LINGER, the application should set l_onoff to a non-zero value, set l_linger to 0 or the desired timeout (in seconds), and call setsockopt. To enable SO_DONTLINGER (i.e. disable SO_LINGER) l_onoff should be set to zero and setsockopt should be called.

By default, a socket may not be bound (see bind) to a local address which is already in use. On occasions, however, it may be desirable to "re-use" an address in this way. Since every connection is uniquely identified by the combination of local and remote addresses, there is no problem with having two sockets bound to the same local address as long as the remote addresses are different. To inform the Windows Sockets implementation that a bind on a socket should not be disallowed because the desired address is already in use by another socket, the application should set the SO_REUSEADDR socket option for the socket before issuing the bind. Note that the option is interpreted only at the time of the bind: it is therefore unnecessary (but harmless) to set the option on a socket which is not to be bound to an existing address, and setting or resetting the option after the bind has no effect on this or any other socket.

An application may request that the Windows Sockets implementation enable the use of "keep-alive" packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets implementation need not support the use of keep-alives: if it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts -- Communication Layers. If a connection is dropped as the result of "keep-alives" the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.

The TCP_NODELAY option disables the Nagle algorithm. The Nagle algorithm is used to reduce the number of small packets sent by a host by buffering unacknowledged send data until a full-size packet can be sent. However, for some applications this algorithm can impede performance, and TCP_NODELAY may be used to turn it off. Application writers should not set TCP_NODELAY unless the impact of doing so is well-understood and desired, since setting TCP_NODELAY can have a significant negative impact of network performance. TCP_NODELAY is the only supported socket option which uses level IPPROTO_TCP; all other options use level SOL_SOCKET.

Windows Sockets suppliers are encouraged (but not required) to supply output debug information if the SO_DEBUG option is set by an application. The mechanism for generating the debug information and the form it takes are beyond the scope of this specification.

The following options are supported for setsockopt. The Type identifies the type of data addressed by optval.

Value	Type	Meaning
SO_BROADCAST	BOOL	Allow transmission of broadcast messages on the socket.
SO_DEBUG	BOOL	Record debugging information.
SO_DONTLINGER	BOOL	Don't block close waiting for unsent data to be sent. Setting this option is equivalent to setting SO_LINGER with l_onoff set to zero.
SO_DONTROUTE	BOOL	Don't route: send directly to interface.
SO_KEEPALIVE	BOOL	Send keepalives
SO_LINGER	struct linger FAR *	Linger on close if unsent data is present
SO_OOBINLINE	BOOL	Receive out-of-band data in the normal data stream.
SO_RCVBUF	int	Specify buffer size for receives
SO_REUSEADDR	BOOL	Allow the socket to be bound to an address which is already in use. (See bind.)
SO_SNDBUF	int	Specify buffer size for sends.
TCP_NODELAY	BOOL	Disables the Nagle algorithm for send coalescing.
BSD options not supported for setsockopt are:

Value	Type	Meaning
SO_ACCEPTCONN	BOOL	Socket is listening
SO_ERROR	int	Get error status and clear
SO_RCVLOWAT	int	Receive low water mark
SO_RCVTIMEO	int	Receive timeout
SO_SNDLOWAT	int	Send low water mark
SO_SNDTIMEO	int	Send timeout
SO_TYPE	int	Type of the socket
IP_OPTIONS		Set options field in IP header.
Return Value

If no error occurs, setsockopt returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEFAULT	optval is not in a valid part of the process address space.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINVAL	level is not valid, or the information in optval is not valid.
WSAENETRESET	Connection has timed out when SO_KEEPALIVE is set.
WSAENOPROTOOPT	The option is unknown or unsupported. In particular, SO_BROADCAST is not supported on sockets of type SOCK_STREAM, while SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER and SO_OOBINLINE are not supported on sockets of type SOCK_DGRAM.
WSAENOTCONN	Connection has been reset when SO_KEEPALIVE is set.
WSAENOTSOCK	The descriptor is not a socket.
See Also

bind, getsockopt, ioctlsocket, socket, WSAAsyncSelect


shutdown()
shutdown

Description

Disable sends and/or receives on a socket.

 	#include <winsock.h>

 	int PASCAL FAR shutdown ( SOCKET s, int how );

s

A descriptor identifying a socket.

how

A flag that describes what types of operation will no longer be allowed.

Remarks

shutdown is used on all types of sockets to disable reception, transmission, or both.

If how is 0, subsequent receives on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP, the TCP window is not changed and incoming data will be accepted (but not acknowledged) until the window is exhausted. For UDP, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

If how is 1, subsequent sends are disallowed. For TCP sockets, a FIN will be sent.

Setting how to 2 disables both sends and receives as described above.

Note that shutdown does not close the socket, and resources attached to the socket will not be freed until closesocket is invoked.

Comments

shutdown does not block regardless of the SO_LINGER setting on the socket.

An application should not rely on being able to re-use a socket after it has been shut down. In particular, a Windows Sockets implementation is not required to support the use of connect on such a socket.

Return Value

If no error occurs, shutdown returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	how is not valid.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAENOTCONN	The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK	The descriptor is not a socket.
See Also

connect, socket


socket()
socket

Description

Create a socket.

 	#include <winsock.h>

 	SOCKET PASCAL FAR socket ( int af, int type, int protocol );

af

An address format specification. The only format currently supported is PF_INET, which is the ARPA Internet address format.

type

A type specification for the new socket.

protocol

A particular protocol to be used with the socket, or 0 if the caller does not wish to specify a protocol.

Remarks

socket allocates a socket descriptor of the specified address family, data type and protocol, as well as related resources. If a protocol is not specified (i.e. equal to 0), the default for the specified connection mode is used.

Only a single protocol exists to support a particular socket type using a given address format. However, the address family may be given as AF_UNSPEC (unspecified), in which case the protocol parameter must be specified. The protocol number to use is particular to the "communication domain" in which communication is to take place.

The following type specifications are supported:

Type	Explanation
SOCK_STREAM	Provides sequenced, reliable, two-way, connection-based byte streams with an out-of-band data transmission mechanism. Uses TCP for the Internet address family.
SOCK_DGRAM	Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses UDP for the Internet address family.
Sockets of type SOCK_STREAM are full-duplex byte streams. A stream socket must be in a connected state before any data may be sent or received on it. A connection to another socket is created with a connect call. Once connected, data may be transferred using send and recv calls. When a session has been completed, a closesocket must be performed. Out-of-band data may also be transmitted as described in send and received as described in recv.

The communications protocols used to implement a SOCK_STREAM ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.

SOCK_DGRAM sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams may be send to that peer send and may be received from (only) this peer using recv.

Return Value

If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEAFNOSUPPORT	The specified address family is not supported.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEMFILE	No more file descriptors are available.
WSAENOBUFS	No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT	The specified protocol is not supported.
WSAEPROTOTYPE	The specified protocol is the wrong type for this socket.
WSAESOCKTNOSUPPORT	The specified socket type is not supported in this address family.
See Also

accept, bind, connect, getsockname, getsockopt, setsockopt, listen, recv, recvfrom, select, send, sendto, shutdown, ioctlsocket


Database Routines


gethostbyaddr()
gethostbyaddr

Description

Get host information corresponding to an address.

 	#include <winsock.h>

 	struct hostent FAR * PASCAL FAR gethostbyaddr ( const char FAR * addr, int len, int type );

addr

A pointer to an address in network byte order.

len

The length of the address, which must be 4 for PF_INET addresses.

type

The type of the address, which must be PF_INET.

Remarks

gethostbyaddr returns a pointer to the following structure which contains the name(s) and address which correspond to the given address.

struct hostent {

char FAR *	h_name;

char FAR * FAR *	h_aliases;

short	h_addrtype;

short	h_length;

char FAR * FAR *	h_addr_list;

};

The members of this structure are:

Element	Usage
h_name	Official name of the host (PC).
h_aliases	A NULL-terminated array of alternate names.
h_addrtype	The type of address being returned; for Windows Sockets this is always PF_INET.
h_length	The length, in bytes, of each address; for PF_INET, this is always 4.
h_addr_list	A NULL-terminated list of addresses for the host. Addresses are returned in network byte order.
The macro h_addr is defined to be h_addr_list[0] for compatibility with older software.

The pointer which is returned points to a structure which is allocated by the Windows Sockets implementation. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

Return Value

If no error occurs, gethostbyaddr returns a pointer to the hostent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetHostByAddr, gethostbyname


gethostbyname()
gethostbyname

Description

Get host information corresponding to a hostname.

 	#include <winsock.h>

 	struct hostent FAR * PASCAL FAR gethostbyname ( const char FAR * name );

name

A pointer to the name of the host.

Remarks

gethostbyname returns a pointer to a hostent structure as described under gethostbyaddr. The contents of this structure correspond to the hostname name.

The pointer which is returned points to a structure which is allocated by the Windows Sockets implementation. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

A gethostbyname implementation must not resolve IP address strings passed to it. Such a request should be treated exactly as if an unknown host name were passed. An application with an IP address string to resolve should use inet_addr to convert the string to an IP address, then gethostbyaddr to obtain the hostent structure.

Return Value

If no error occurs, gethostbyname returns a pointer to the hostent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetHostByName, gethostbyaddr


gethostname()
gethostname

Description

Return the standard host name for the local machine.

#include <winsock.h>

int PASCAL FAR gethostname ( char FAR * name, int namelen );

name

A pointer to a buffer that will receive the host name.

namelen

The length of the buffer.

Remarks

This routine returns the name of the local host into the buffer specified by the name parameter. The host name is returned as a null-terminated string. The form of the host name is dependent on the Windows Sockets implementation--it may be a simple host name, or it may be a fully qualified domain name. However, it is guaranteed that the name returned will be successfully parsed by gethostbyname and WSAAsyncGetHostByName.

Return Value

If no error occurs, gethostname returns 0, otherwise it returns SOCKET_ERROR and a specific error code may be retrieved by calling WSAGetLastError.

Error Codes

WSAEFAULT	The namelen parameter is too small.
WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
See Also

gethostbyname, WSAAsyncGetHostByName.


getprotobyname()
getprotobyname

Description

Get protocol information corresponding to a protocol name.

 	#include <winsock.h>

 	struct protoent FAR * PASCAL FAR getprotobyname ( const char FAR * name );

name

A pointer to a protocol name.

Remarks

getprotobyname returns a pointer to the following structure which contains the name(s) and protocol number which correspond to the given protocol name.

struct protoent {

char FAR *	p_name;

char FAR * FAR *	p_aliases;

short	p_proto;

};

The members of this structure are:

Element	Usage
p_name	Official name of the protocol.
p_aliases	A NULL-terminated array of alternate names.
p_proto	The protocol number, in host byte order.
The pointer which is returned points to a structure which is allocated by the Windows Sockets library. The application must never attempt to modify this structure or to free any of its components. Furthermore only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

Return Value

If no error occurs, getprotobyname returns a pointer to the protoent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetProtoByName, getprotobynumber


getprotobynumber()
getprotobynumber

Description

Get protocol information corresponding to a protocol number.

 	#include <winsock.h>

 	struct protoent FAR * PASCAL FAR getprotobynumber ( int number );

number

A protocol number, in host byte order.

Remarks

This function returns a pointer to a protoent structure as described above in getprotobyname. The contents of the structure correspond to the given protocol number.

The pointer which is returned points to a structure which is allocated by the Windows Sockets implementation. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

Return Value

If no error occurs, getprotobynumber returns a pointer to the protoent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetProtoByNumber, getprotobyname


getservbyname()
getservbyname

Description

Get service information corresponding to a service name and protocol.

 	#include <winsock.h>

 	struct servent FAR * PASCAL FAR getservbyname ( const char FAR * name,

const char FAR * proto );

name

A pointer to a service name.

proto

An optional pointer to a protocol name. If this is NULL, getservbyname returns the first service entry for which the name matches the s_name or one of the s_aliases. Otherwise getservbyname matches both the name and the proto.

Remarks

getservbyname returns a pointer to the following structure which contains the name(s) and service number which correspond to the given service name.

struct servent {

char FAR *	s_name;

char FAR * FAR *	s_aliases;

short	s_port;

char FAR *	s_proto;

};

The members of this structure are:

Element	Usage
s_name	Official name of the service.
s_aliases	A NULL-terminated array of alternate names.
s_port	The port number at which the service may be contacted. Port numbers are returned in network byte order.
s_proto	The name of the protocol to use when contacting the service.
The pointer which is returned points to a structure which is allocated by the Windows Sockets library. The application must never attempt to modify this structure or to free any of its components. Furthermore only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

Return Value

If no error occurs, getservbyname returns a pointer to the servent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetServByName, getservbyport


getservbyport()
getservbyport

Description

Get service information corresponding to a port and protocol.

 	#include <winsock.h>

 	struct servent FAR * PASCAL FAR getservbyport ( int port, const char FAR * proto );

port

The port for a service, in network byte order.

proto

An optional pointer to a protocol name. If this is NULL, getservbyport returns the first service entry for which the port matches the s_port. Otherwise getservbyport matches both the port and the proto.

Remarks

getservbyport returns a pointer a servent structure as described above for getservbyname.

The pointer which is returned points to a structure which is allocated by the Windows Sockets implementation. The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, and so the application should copy any information which it needs before issuing any other Windows Sockets API calls.

Return Value

If no error occurs, getservbyport returns a pointer to the servent structure described above. Otherwise it returns a NULL pointer and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEINTR	The (blocking) call was canceled via WSACancelBlockingCall.
See Also

WSAAsyncGetServByPort, getservbyname


Microsoft Windows-specific Extensions


WSAAsyncGetHostByAddr()
WSAAsyncGetHostByAddr

Description

Get host information corresponding to an address - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetHostByAddr ( HWND hWnd,

unsigned int wMsg, const char FAR * addr, int len, int type, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

addr

A pointer to the network address for the host. Host addresses are stored in network byte order.

len

The length of the address, which must be 4 for PF_INET.

type

The type of the address, which must be PF_INET.

buf

A pointer to the data area to receive the hostent data. Note that this must be larger than the size of a hostent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a hostent structure but any and all of the data which is referenced by members of the hostent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of gethostbyaddr, and is used to retrieve host name and address information corresponding to a network address. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a hostent structure. To access the elements of this structure, the original buffer address should be cast to a hostent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetHostByAddr function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetHostByAddr returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncGetHostByAddr returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a hostent structure together with the contents of data areas referenced by members of the same hostent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

gethostbyaddr, WSACancelAsyncRequest


WSAAsyncGetHostByName()
WSAAsyncGetHostByName

Description

Get host information corresponding to a hostname - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetHostByName ( HWND hWnd,

unsigned int wMsg, const char FAR * name, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

name

A pointer to the name of the host.

buf

A pointer to the data area to receive the hostent data. Note that this must be larger than the size of a hostent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a hostent structure but any and all of the data which is referenced by members of the hostent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of gethostbyname, and is used to retrieve host name and address information corresponding to a hostname. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a hostent structure. To access the elements of this structure, the original buffer address should be cast to a hostent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetHostByName function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetHostByName returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncGetHostByName returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a hostent structure together with the contents of data areas referenced by members of the same hostent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

gethostbyname, WSACancelAsyncRequest


WSAAsyncGetProtoByName()
WSAAsyncGetProtoByName

Description

Get protocol information corresponding to a protocol name - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetProtoByName ( HWND hWnd,

unsigned int wMsg, const char FAR * name, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

name

A pointer to the protocol name to be resolved.

buf

A pointer to the data area to receive the protoent data. Note that this must be larger than the size of a protoent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a protoent structure but any and all of the data which is referenced by members of the protoent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of getprotobyname, and is used to retrieve the protocol name and number corresponding to a protocol name. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a protoent structure. To access the elements of this structure, the original buffer address should be cast to a protoent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetProtoByName function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetProtoByName returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncGetProtoByName returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a protoent structure together with the contents of data areas referenced by members of the same protoent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

getprotobyname, WSACancelAsyncRequest


WSAAsyncGetProtoByNumber()
WSAAsyncGetProtoByNumber

Description

Get protocol information corresponding to a protocol number - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetProtoByNumber ( HWND hWnd,

unsigned int wMsg, int number, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

number

The protocol number to be resolved, in host byte order.

buf

A pointer to the data area to receive the protoent data. Note that this must be larger than the size of a protoent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a protoent structure but any and all of the data which is referenced by members of the protoent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of getprotobynumber, and is used to retrieve the protocol name and number corresponding to a protocol number. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a protoent structure. To access the elements of this structure, the original buffer address should be cast to a protoent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetProtoByNumber function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetProtoByNumber returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncGetProtoByNumber returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a protoent structure together with the contents of data areas referenced by members of the same protoent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

getprotobynumber, WSACancelAsyncRequest


WSAAsyncGetServByName()
WSAAsyncGetServByName

Description

Get service information corresponding to a service name and port - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetServByName ( HWND hWnd,

unsigned int wMsg, const char FAR * name, const char FAR * proto, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

name

A pointer to a service name.

proto

A pointer to a protocol name. This may be NULL, in which case WSAAsyncGetServByName will search for the first service entry for which s_name or one of the s_aliases matches the given name. Otherwise WSAAsyncGetServByName matches both name and proto.

buf

A pointer to the data area to receive the servent data. Note that this must be larger than the size of a servent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a servent structure but any and all of the data which is referenced by members of the servent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of getservbyname, and is used to retrieve service information corresponding to a service name. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a hostent structure. To access the elements of this structure, the original buffer address should be cast to a hostent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetServByName function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetServByName returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncServByName returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a hostent structure together with the contents of data areas referenced by members of the same hostent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

getservbyname, WSACancelAsyncRequest


WSAAsyncGetServByPort()
WSAAsyncGetServByPort

Description

Get service information corresponding to a port and protocol - asynchronous version.

 	#include <winsock.h>

 	HANDLE PASCAL FAR WSAAsyncGetServByPort ( HWND hWnd,

unsigned int wMsg, int port, const char FAR * proto, char FAR * buf, int buflen );

hWnd

The handle of the window which should receive a message when the asynchronous request completes.

wMsg

The message to be received when the asynchronous request completes.

port

The port for the service, in network byte order.

proto

A pointer to a protocol name. This may be NULL, in which case WSAAsyncGetServByPort will search for the first service entry for which s_port match the given port. Otherwise WSAAsyncGetServByPort matches both port and proto.

buf

A pointer to the data area to receive the servent data. Note that this must be larger than the size of a servent structure. This is because the data area supplied is used by the Windows Sockets implementation to contain not only a servent structure but any and all of the data which is referenced by members of the servent structure. It is recommended that you supply a buffer of MAXGETHOSTSTRUCT bytes.

buflen

The size of data area buf above.

Remarks

This function is an asynchronous version of getservbyport, and is used to retrieve service information corresponding to a port number. The Windows Sockets implementation initiates the operation and returns to the caller immediately, passing back an asynchronous task handle which the application may use to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.

When the asynchronous operation is complete the application's window hWnd receives message wMsg. The wParam argument contains the asynchronous task handle as returned by the original function call. The high 16 bits of lParam contain any error code. The error code may be any error as defined in winsock.h. An error code of zero indicates successful completion of the asynchronous operation. On successful completion, the buffer supplied to the original function call contains a servent structure. To access the elements of this structure, the original buffer address should be cast to a servent structure pointer and accessed as appropriate.

Note that if the error code is WSAENOBUFS, it indicates that the size of the buffer specified by buflen in the original call was too small to contain all the resultant information. In this case, the low 16 bits of lParam contain the size of buffer required to supply ALL the requisite information. If the application decides that the partial data is inadequate, it may reissue the WSAAsyncGetServByPort function call with a buffer large enough to receive all the desired information (i.e. no smaller than the low 16 bits of lParam).

The error code and buffer length should be extracted from the lParam using the macros WSAGETASYNCERROR and WSAGETASYNCBUFLEN, defined in winsock.h as:

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

Return Value

The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply success or failure of the operation itself.

If the operation was successfully initiated, WSAAsyncGetServByPort returns a nonzero value of type HANDLE which is the asynchronous task handle for the request. This value can be used in two ways. It can be used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion messages, by examining the wParam message argument.

If the asynchronous operation could not be initiated, WSAAsyncGetServByPort returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

The buffer supplied to this function is used by the Windows Sockets implementation to construct a servent structure together with the contents of data areas referenced by members of the same servent structure. To avoid the WSAENOBUFS error noted above, the application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in winsock.h).

Notes For Windows Sockets Suppliers

It is the responsibility of the Windows Sockets implementation to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation must re-post that message as long as the window exists.

Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.

Error Codes

The following error codes may be set when an application window receives a message. As described above, they may be extracted from the lParam in the reply message using the WSAGETASYNCERROR macro.

WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAENOBUFS	No/insufficient buffer space is available
WSAHOST_NOT_FOUND	Authoritative Answer Host not found.
WSATRY_AGAIN	Non-Authoritative Host not found, or SERVERFAIL.
WSANO_RECOVERY	Non recoverable errors, FORMERR, REFUSED, NOTIMP.
WSANO_DATA	Valid name, no data record of requested type.
The following errors may occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEWOULDBLOCK	The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
See Also

getservbyport, WSACancelAsyncRequest


WSAAsyncSelect()
WSAAsyncSelect

Description

Request event notification for a socket.

 	#include <winsock.h>

 	int PASCAL FAR WSAAsyncSelect ( SOCKET s, HWND hWnd,

unsigned int wMsg, long lEvent );

s

A descriptor identifying the socket for which event notification is required.

hWnd

A handle identifying the window which should receive a message when a network event occurs.

wMsg

The message to be received when a network event occurs.

lEvent

A bitmask which specifies a combination of network events in which the application is interested.

Remarks

This function is used to request that the Windows Sockets DLL should send a message to the window hWnd whenever it detects any of the network events specified by the lEvent parameter. The message which should be sent is specified by the wMsg parameter. The socket for which notification is required is identified by s.

This function automatically sets socket s to non-blocking mode.

The lEvent parameter is constructed by or'ing any of the values specified in the following list.

Value	Meaning
FD_READ	Want to receive notification of readiness for reading
FD_WRITE	Want to receive notification of readiness for writing
FD_OOB	Want to receive notification of the arrival of out-of-band data
FD_ACCEPT	Want to receive notification of incoming connections
FD_CONNECT	Want to receive notification of completed connection
FD_CLOSE	Want to receive notification of socket closure
Issuing a WSAAsyncSelect for a socket cancels any previous WSAAsyncSelect for the same socket. For example, to receive notification for both reading and writing, the application must call WSAAsyncSelect with both FD_READ and FD_WRITE, as follows:

rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);

It is not possible to specify different messages for different events. The following code will not work; the second call will cancel the effects of the first, and only FD_WRITE events will be reported with message wMsg2:

rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);

rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);

To cancel all notification − i.e., to indicate that the Windows Sockets implementation should send no further messages related to network events on the socket − lEvent should be set to zero.

rc = WSAAsyncSelect(s, hWnd, 0, 0);

Although in this instance WSAAsyncSelect immediately disables event message posting for the socket, it is possible that messages may be waiting in the application's message queue. The application must therefore be prepared to receive network event messages even after cancellation. Closing a socket with closesocket also cancels WSAAsyncSelect message sending, but the same caveat about messages in the queue prior to the closesocket still applies.

Since an accept'ed socket has the same properties as the listening socket used to accept it, any WSAAsyncSelect events set for the listening socket apply to the accepted socket. For example, if a listening socket has WSAAsyncSelect events FD_ACCEPT, FD_READ, and FD_WRITE, then any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE events with the same wMsg value used for messages. If a different wMsg or events are desired, the application should call WSAAsyncSelect, passing the accepted socket and the desired new information. (Note that there is a timing window between the accept call and the call to WSAAsyncSelect to change the events or wMsg. An application which desires a different wMsg for the listening and accept'ed sockets should ask for only FD_ACCEPT events on the listening socket, then set appropriate events after the accept. Since FD_ACCEPT is never sent for a connected socket and FD_READ, FD_WRITE, FD_OOB, and FD_CLOSE are never sent for listening sockets, this will not impose difficulties.)

When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam argument identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in winsock.h.

The error and event codes may be extracted from the lParam using the macros WSAGETSELECTERROR and WSAGETSELECTEVENT, defined in winsock.h as:

#define WSAGETSELECTERROR(lParam)  HIWORD(lParam)

#define WSAGETSELECTEVENT(lParam)  LOWORD(lParam)

The use of these macros will maximize the portability of the source code for the application.

The possible network event codes which may be returned are as follows:

Value	Meaning
FD_READ	Socket s ready for reading
FD_WRITE	Socket s ready for writing
FD_OOB	Out-of-band data ready for reading on socket s.
FD_ACCEPT	Socket s ready for accepting a new incoming connection
FD_CONNECT	Connection on socket s completed
FD_CLOSE	Connection identified by socket s has been closed
Return Value

The return value is 0 if the application's declaration of interest in the network event set was successful. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

Although WSAAsyncSelect can be called with interest in multiple events, the application window will receive a single message for each network event.

As in the case of the select function, WSAAsyncSelect will frequently be used to determine when a data transfer operation (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for the possibility that it may receive a message and issue a Windows Sockets API call which returns WSAEWOULDBLOCK immediately. For example, the following sequence of events is possible:

1.	data arrives on socket s; Windows Sockets posts WSAAsyncSelect message

2.	application processes some other message

3.	while processing, application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read

4.	application issues a recv(s,...) to read the data

5.	application loops to process next message, eventually reaching the WSAAsyncSelect message indicating that data is ready to read

6.	application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.

Other sequences are possible.

The Windows Sockets DLL will not continually flood an application with messages for a particular network event. Having successfully posted notification of a particular event to an application window, no further message(s) for that network event will be posted to the application window until the application makes the function call which implicitly reenables notification of that network event.

Event	Re-enabling function
FD_READ	recv or recvfrom
FD_WRITE	send or sendto
FD_OOB	recv
FD_ACCEPT	accept
FD_CONNECT	NONE
FD_CLOSE	NONE
Any call to the reenabling routine, even one which fails, results in reenabling of message posting for the relevant event.

For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggered." This means that if the reenabling routine is called and the relevant event is still valid after the call, a WSAAsyncSelect message is posted to the application. This allows an application to be event-driven and not concern itself with the amount of data that arrives at any one time. Consider the following sequence:

1.	Windows Sockets DLL receives 100 bytes of data on socket s and posts an FD_READ message.

2.	The application issues recv( s, buffptr, 50, 0) to read 50 bytes.

3.	The Windows Sockets DLL posts another FD_READ message since there is still data to be read.

With these semantics, an application need not read all available data in response to an FD_READ message--a single recv in response to each FD_READ message is appropriate. If an application issues multiple recv calls in response to a single FD_READ, it may receive multiple FD_READ messages. Such an application may wish to disable FD_READ messages before starting the recv calls by calling WSAAsyncSelect with the FD_READ event not set.

If an event is true when the application initially calls WSAAsyncSelect or when the reenabling function is called, then a message is posted as appropriate. For example, if an application calls listen, a connect attempt is made, then the application calls WSAAsyncSelect specifying that it wants to receive FD_ACCEPT messages for the socket, the Windows Sockets implementation posts an FD_ACCEPT message immediately.

The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket is first connected with connect or accepted with accept, and then after a send or sendto fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will be notified that sends are again possible with an FD_WRITE message.

The FD_OOB event is used only when a socket is configured to receive out-of-band data separately. If the socket is configured to receive out-of-band data in-line, the out-of-band (expedited) data is treated as normal data and the application should register an interest in, and will receive, FD_READ events, not FD_OOB events. An application may set or inspect the way in which out-of-band data is to be handled by using setsockopt or getsockopt for the SO_OOBINLINE option.

The error code in an FD_CLOSE message indicates whether the socket close was graceful or abortive. If the error code is 0, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual socket was reset. This only applies to sockets of type SOCK_STREAM.

The FD_CLOSE message is posted when a close indication is received for the virtual circuit corresponding to the socket. In TCP terms, this means that the FD_CLOSE is posted when the connection goes into the FIN WAIT or CLOSE WAIT states. This results from the remote end performing a shutdown on the send side or a closesocket.

Please note your application will receive ONLY an FD_CLOSE message to indicate closure of a virtual circuit. It will NOT receive an FD_READ message to indicate this condition.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	Indicates that one of the specified parameters was invalid
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
	Additional error codes may be set when an application window receives a message. This error code is extracted from the lParam in the reply message using the WSAGETSELECTERROR macro. Possible error codes for each network event are:
Event: FD_CONNECT
Error Code		Meaning
WSAEADDRINUSE	The specified address is already in use.
WSAEADDRNOTAVAIL	The specified address is not available from the local machine.
WSAEAFNOSUPPORT	Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED	The attempt to connect was forcefully rejected.
WSAEDESTADDRREQ	A destination address is required.
WSAEFAULT	The namelen argument is incorrect.
WSAEINVAL	The socket is already bound to an address.
WSAEISCONN	The socket is already connected.
WSAEMFILE	No more file descriptors are available.
WSAENETUNREACH	The network can't be reached from this host at this time.
WSAENOBUFS	No buffer space is available. The socket cannot be connected.
WSAENOTCONN	The socket is not connected.
WSAENOTSOCK	The descriptor is a file, not a socket.
WSAETIMEDOUT	Attempt to connect timed out without establishing a connection
Event: FD_CLOSE
Error Code		Meaning
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAECONNRESET	The connection was reset by the remote side.
WSAECONNABORTED	The connection was aborted due to timeout or other failure.
Event: FD_READ
Event: FD_WRITE
Event: FD_OOB
Event: FD_ACCEPT
Error Code		Meaning
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
Notes For Windows Sockets Suppliers	It is the responsibility of the Windows Sockets Supplier to ensure that messages are successfully posted to the application. If a PostMessage operation fails, the Windows Sockets implementation MUST re-post that message as long as the window exists.
Windows Sockets suppliers should use the WSAMAKESELECTREPLY macro when constructing the lParam in the message.
When a socket is closed, the Windows Sockets Supplier should purge any messages remaining for posting to the application window. However the application must be prepared to receive, and discard, any messages which may have been posted prior to the closesocket.
See Also

select


WSACancelAsyncRequest()
WSACancelAsyncRequest

Description

Cancel an incomplete asynchronous operation.

 	#include <winsock.h>

 	int PASCAL FAR WSACancelAsyncRequest ( HANDLE hAsyncTaskHandle );

hAsyncTaskHandle

Specifies the asynchronous operation to be canceled.

Remarks

The WSACancelAsyncRequest function is used to cancel an asynchronous operation which was initiated by one of the WSAAsyncGetXByY functions such as WSAAsyncGetHostByName. The operation to be canceled is identified by the hAsyncTaskHandle parameter, which should be set to the asynchronous task handle as returned by the initiating function.

Return Value

The value returned by WSACancelAsyncRequest is 0 if the operation was successfully canceled. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

An attempt to cancel an existing asynchronous WSAAsyncGetXByY operation can fail with an error code of WSAEALREADY for two reasons. First, the original operation has already completed and the application has dealt with the resultant message. Second, the original operation has already completed but the resultant message is still waiting in the application window queue.

Notes For Windows Sockets Suppliers

It is unclear whether the application can usefully distinguish between WSAEINVAL and WSAEALREADY, since in both cases the error indicates that there is no asynchronous operation in progress with the indicated handle. [Trivial exception: 0 is always an invalid asynchronous task handle.] The Windows Sockets specification does not prescribe how a conformant Windows Sockets implementation should distinguish between the two cases. For maximum portability, a Windows Sockets application should treat the two errors as equivalent.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	Indicates that the specified asynchronous task handle was invalid
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
WSAEALREADY	The asynchronous routine being canceled has already completed.
See Also

WSAAsyncGetHostByAddr,
WSAAsyncGetHostByName,
WSAAsyncGetProtoByNumber,
WSAAsyncGetProtoByName,
WSAAsyncGetHostByName,
WSAAsyncGetServByPort,
WSAAsyncGetServByName


WSACancelBlockingCall()
WSACancelBlockingCall

Description

Cancel a blocking call which is currently in progress.

 	#include <winsock.h>

 	int PASCAL FAR WSACancelBlockingCall ( void );

Remarks

This function cancels any outstanding blocking operation for this task. It is normally used in two situations:

1.	An application is processing a message which has been received while a blocking call is in progress. In this case, WSAIsBlocking will be true.

2.	A blocking call is in progress, and Windows Sockets has called back to the application's "blocking hook" function (as established by WSASetBlockingHook).

In each case, the original blocking call will terminate as soon as possible with the error WSAEINTR. (In (1), the termination will not take place until Windows message scheduling has caused control to revert to the blocking routine in Windows Sockets. In (2), the blocking call will be terminated as soon as the blocking hook function completes.)

In the case of a blocking connect operation, the Windows Sockets implementation will terminate the blocking call as soon as possible, but it may not be possible for the socket resources to be released until the connection has completed (and then been reset) or timed out. This is likely to be noticeable only if the application immediately tries to open a new socket (if no sockets are available), or to connect to the same peer.

Cancelling an accept or a select call does not adversely impact the sockets passed to these calls. Only the particular call fails; any operation that was legal before the cancel is legal after the cancel, and the state of the socket is not affected in any way.

Cancelling any operation other than accept and select can leave the socket in an indeterminate state. If an application cancels a blocking operation on a socket, the only operation that the application can depend on being able to perform on the socket is a call to closesocket, although other operations may work on some Windows Sockets implementations. If an application desires maximum portability, it must be careful not to depend on performing operations after a cancel. An application may reset the connection by setting the timeout on SO_LINGER to 0.

If a cancel operation compromised the integrity of a SOCK_STREAM's data stream in any way, the Windows Sockets implementation must reset the connection and fail all future operations other than closesocket with WSAECONNABORTED.

Return Value

The value returned by WSACancelBlockingCall is 0 if the operation was successfully canceled. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

Note that it is possible that the network operation completes before the WSACancelBlockingCall is processed, for example if data is received into the user buffer at interrupt time while the application is in a blocking hook. In this case, the blocking operation will return successfully as if WSACancelBlockingCall had never been called. Note that the WSACancelBlockingCall still succeeds in this case; the only way to know with certainty that an operation was actually canceled is to check for a return code of WSAEINTR from the blocking call.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINVAL	Indicates that there is no outstanding blocking call.


WSACleanup()
WSACleanup

Description

Terminate use of the Windows Sockets DLL.

 	#include <winsock.h>

 	int PASCAL FAR WSACleanup ( void );

Remarks

An application or DLL is required to perform a (successful) WSAStartup call before it can use Windows Sockets services. When it has completed the use of Windows Sockets, the application or DLL must call WSACleanup to deregister itself from a Windows Sockets implementation and allow the implementation to free any resources allocated on behalf of the application or DLL. Any open SOCK_STREAM sockets that are connected when WSACleanup is called are reset; sockets which have been closed with closesocket but which still have pending data to be sent are not affected--the pending data is still sent.

There must be a call to WSACleanup for every call to WSAStartup made by a task. Only the final WSACleanup for that task does the actual cleanup; the preceding calls simply decrement an internal reference count in the Windows Sockets DLL. A naive application may ensure that WSACleanup was called enough times by calling WSACleanup in a loop until it returns WSANOTINITIALISED.

Return Value

The return value is 0 if the operation was successful. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Comments

Attempting to call WSACleanup from within a blocking hook and then failing to check the return code is a common Windows Sockets programming error. If an application needs to quit while a blocking call is outstanding, the application must first cancel the blocking call with WSACancelBlockingCall then issue the WSACleanup call once control has been returned to the application.

Notes For Windows Sockets Suppliers

Well-behaved Windows Sockets applications will make a WSACleanup call to indicate deregistration from a Windows Sockets implementation. This function can thus, for example, be utilized to free up resources allocated to the specific application.

A Windows Sockets implementation must be prepared to deal with an application which terminates without invoking WSACleanup - for example, as a result of an error.

In a multithreaded environment, WSACleanup terminates Windows Sockets operations for all threads.

A Windows Sockets implementation must ensure that WSACleanup leaves things in a state in which the application can invoke WSAStartup to re-establish Windows Sockets usage.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
See Also

WSAStartup


WSAGetLastError()
WSAGetLastError

Description

Get the error status for the last operation which failed.

 	#include <winsock.h>

 	int PASCAL FAR WSAGetLastError ( void );

Remarks

This function returns the last network error that occurred. When a particular Windows Sockets API function indicates that an error has occurred, this function should be called to retrieve the appropriate error code.

Return Value

The return value indicates the error code for the last Windows Sockets API routine performed by this thread.

Notes For Windows Sockets Suppliers

The use of the WSAGetLastError function to retrieve the last error code, rather than relying on a global error variable (cf. errno), is required in order to provide compatibility with future multi-threaded environments.

Note that in a nonpreemptive Windows environment WSAGetLastError is used to retrieve only Windows Sockets API errors. In a preemptive environment, WSAGetLastError will invoke GetLastError, which is used to retrieve the error status for all Win32 API functions on a per-thread basis. For portability, an application should use WSAGetLastError immediately after the Windows Sockets API function which failed.

See Also

WSASetLastError


WSAIsBlocking()
WSAIsBlocking

Description

Determine if a blocking call is in progress.

 	#include <winsock.h>

 	BOOL PASCAL FAR WSAIsBlocking ( void );

Remarks

This function allows a task to determine if it is executing while waiting for a previous blocking call to complete.

Return Value

The return value is TRUE if there is an outstanding blocking function awaiting completion. Otherwise, it is FALSE.

Comments

Although a call issued on a blocking socket appears to an application program as though it "blocks", the Windows Sockets DLL has to relinquish the processor to allow other applications to run. This means that it is possible for the application which issued the blocking call to be re-entered, depending on the message(s) it receives. In this instance, the WSAIsBlocking function can be used to ascertain whether the task has been re-entered while waiting for an outstanding blocking call to complete. Note that Windows Sockets prohibits more than one outstanding call per thread.

Notes For Windows Sockets Suppliers

A Windows Sockets implementation must prohibit more than one outstanding blocking call per thread.


WSASetBlockingHook()
WSASetBlockingHook

Description

Establish an application-specific blocking hook function.

 	#include <winsock.h>

 	FARPROC PASCAL FAR WSASetBlockingHook ( FARPROC lpBlockFunc );

lpBlockFunc

A pointer to the procedure instance address of the blocking function to be installed.

Remarks

This function installs a new function which a Windows Sockets implementation should use to implement blocking socket function calls.

A Windows Sockets implementation includes a default mechanism by which blocking socket functions are implemented. The function WSASetBlockingHook gives the application the ability to execute its own function at "blocking" time in place of the default function.

When an application invokes a blocking Windows Sockets API operation, the Windows Sockets implementation initiates the operation and then enters a loop which is similar to the following pseudocode:

for(;;) {

 /* flush messages for good user response */

 while(BlockingHook)

  ;

 /* check for WSACancelBlockingCall */

 if(operation_cancelled)

  break;

 /* check to see if operation completed */

 if(operation_complete)

  break; /* normal completion */

}

Note that Windows Sockets implementations may perform the above steps in a different order; for example, the check for operation complete may occur before calling the blocking hook. The default BlockingHook function is equivalent to:

BOOL DefaultBlockingHook(void) {

 MSG msg;

 BOOL ret;

 /* get the next message if any */

 ret = (BOOL)PeekMessage(&msg,NULL,0,0,PM_REMOVE);

 /* if we got one, process it */

 if (ret) {

  TranslateMessage(&msg);

  DispatchMessage(&msg);

 }

 /* TRUE if we got a message */

 return ret;

}

The WSASetBlockingHook function is provided to support those applications which require more complex message processing - for example, those employing the MDI (multiple document interface) model. It is not intended as a mechanism for performing general applications functions. In particular, the only Windows Sockets API function which may be issued from a custom blocking hook function is WSACancelBlockingCall, which will cause the blocking loop to terminate.

This function must be implemented on a per-task basis for non-multithreaded versions of Windows and on a per-thread basis for multithreaded versions of Windows such as Windows NT. It thus provides for a particular task or thread to replace the blocking mechanism without affecting other tasks or threads.

In multithreaded versions of Windows, there is no default blocking hook--blocking calls block the thread that makes the call. However, an application may install a specific blocking hook by calling WSASetBlockingHook.

This allows easy portability of applications that depend on the blocking hook behavior.

Return Value

The return value is a pointer to the procedure-instance of the previously installed blocking function. The application or library that calls the WSASetBlockingHook  function should save this return value so that it can be restored if necessary. (If "nesting" is not important, the application may simply discard the value returned by WSASetBlockingHook and eventually use WSAUnhookBlockingHook to restore the default mechanism.) If the operation fails, a NULL pointer is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
WSAENETDOWN	The Windows Sockets implementation has detected that the network subsystem has failed.
WSAEINPROGRESS	A blocking Windows Sockets operation is in progress.
See Also

WSAUnhookBlockingHook


WSASetLastError()
WSASetLastError

Description

Set the error code which can be retrieved by WSAGetLastError.

 	#include <winsock.h>

 	void PASCAL FAR WSASetLastError ( int iError );

Remarks

This function allows an application to set the error code to be returned by a subsequent WSAGetLastError call for the current thread. Note that any subsequent Windows Sockets routine called by the application will override the error code as set by this routine.

iError

Specifies the error code to be returned by a subsequent WSAGetLastError call.

Notes For Windows Sockets Suppliers

In a Win32 environment, this function will invoke SetLastError.

Return Value

None.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
See Also

WSAGetLastError


WSAStartup()
WSAStartup

Description

 	#include <winsock.h>

 	int PASCAL FAR WSAStartup ( WORD wVersionRequested,

LPWSADATA lpWSAData );

wVersionRequested

The highest version of Windows Sockets API support that the caller can use. The high order byte specifies the minor version (revision) number; the low-order byte specifies the major version number.

lpWSAData

A pointer to the WSADATA data structure that is to receive details of the Windows Sockets implementation.

Remarks

This function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets API required and to retrieve details of the specific Windows Sockets implementation. The application or DLL may only issue further Windows Sockets API functions after a successful WSAStartup invocation.

In order to support future Windows Sockets implementations and applications which may have functionality differences from Windows Sockets 1.1, a negotiation takes place in WSAStartup. The caller of WSAStartup and the Windows Sockets DLL indicate to each other the highest version that they can support, and each confirms that the other's highest version is acceptable. Upon entry to WSAStartup, the Windows Sockets DLL examines the version requested by the application. If this version is higher than the lowest version supported by the DLL, the call succeeds and the DLL returns in wHighVersion the highest version it supports and in wVersion the minimum of its high version and wVersionRequested. The Windows Sockets DLL then assumes that the application will use wVersion. If the wVersion field of the WSADATA structure is unacceptable to the caller, it should call WSACleanup and either search for another Windows Sockets DLL or fail to initialize.

This negotiation allows both a Windows Sockets DLL and a Windows Sockets application to support a range of Windows Sockets versions. An application can successfully utilize a Windows Sockets DLL if there is any overlap in the version ranges. The following chart gives examples of how WSAStartup works in conjunction with different application and Windows Sockets DLL versions:

App versions	DLL Versions	wVersionRequested	wVersion	wHighVersion	End Result
1.1	1.1	1.1	1.1	1.1	use 1.1
1.0 1.1	1.0	1.1	1.0	1.0	use 1.0
1.0	1.0 1.1	1.0	1.0	1.1	use 1.0
1.1	1.0 1.1	1.1	1.1	1.1	use 1.1
1.1	1.0	1.1	1.0	1.0	Application fails
1.0	1.1	1.0	---	---	WSAVERNOTSUPPORTED
1.0 1.1	1.0 1.1	1.1	1.1	1.1	use 1.1
1.1 2.0	1.1	2.0	1.1	1.1	use 1.1
2.0	1.1	2.0	1.1	1.1	Application fails
The following code fragment demonstrates how an application which supports only version 1.1 of Windows Sockets makes a WSAStartup call:

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {

 /* Tell the user that we couldn't find a useable */

 /* winsock.dll.     */

 return;

}

/* Confirm that the Windows Sockets DLL supports 1.1.*/

/* Note that if the DLL supports versions greater */

/* than 1.1 in addition to 1.1, it will still return */

/* 1.1 in wVersion since that is the version we */

/* requested.     */

if ( LOBYTE( wsaData.wVersion ) != 1 ||

  HIBYTE( wsaData.wVersion ) != 1 ) {

 /* Tell the user that we couldn't find a useable */

 /* winsock.dll.     */

 WSACleanup( );

 return;

}

/* The Windows Sockets DLL is acceptable. Proceed. */

And this code fragment demonstrates how a Windows Sockets DLL which supports only version 1.1 performs the WSAStartup negotiation:

/* Make sure that the version requested is >= 1.1. */

/* The low byte is the major version and the high */

/* byte is the minor version.   */

if ( LOBYTE( wVersionRequested ) < 1 ||

 ( LOBYTE( wVersionRequested ) == 1 &&

 HIBYTE( wVersionRequested ) < 1 ) {

 return WSAVERNOTSUPPORTED;

}

/* Since we only support 1.1, set both wVersion and */

/* wHighVersion to 1.1.    */

lpWsaData->wVersion = MAKEWORD( 1, 1 );

lpWsaData->wHighVersion = MAKEWORD( 1, 1 );

Once an application or DLL has made a successful WSAStartup call, it may proceed to make other Windows Sockets API calls as needed. When it has finished using the services of the Windows Sockets DLL, the application or DLL must call WSACleanup in order to allow the Windows Sockets DLL to free any resources for the application.

Details of the actual Windows Sockets implementation are described in the WSAData structure defined as follows:

struct WSAData {

WORD	wVersion;

WORD	wHighVersion;

char 	szDescription[WSADESCRIPTION_LEN+1];

char	szSystemStatus[WSASYSSTATUS_LEN+1];

unsigned short	iMaxSockets;

unsigned short	iMaxUdpDg;

char FAR *	lpVendorInfo;

};

The members of this structure are:

Element	Usage
wVersion	The version of the Windows Sockets specification that the Windows Sockets DLL expects the caller to use.
wHighVersion	The highest version of the Windows Sockets specification that this DLL can support (also encoded as above). Normally this will be the same as wVersion.
szDescription	A null-terminated ASCII string into which the Windows Sockets DLL copies a description of the Windows Sockets implementation, including vendor identification. The text (up to 256 characters in length) may contain any characters, but vendors are cautioned against including control and formatting characters: the most likely use that an application will put this to is to display it (possibly truncated) in a status message.
szSystemStatus	A null-terminated ASCII string into which the Windows Sockets DLL copies relevant status or configuration information. The Windows Sockets DLL should use this field only if the information might be useful to the user or support staff: it should not be considered as an extension of the szDescription field.
iMaxSockets	The maximum number of sockets which a single process can potentially open. A Windows Sockets implementation may provide a global pool of sockets for allocation to any process; alternatively it may allocate per-process resources for sockets. The number may well reflect the way in which the Windows Sockets DLL or the networking software was configured. Application writers may use this number as a crude indication of whether the Windows Sockets implementation is usable by the application. For example, an X Windows server might check iMaxSockets when first started: if it is less than 8, the application would display an error message instructing the user to reconfigure the networking software. (This is a situation in which the szSystemStatus text might be used.) Obviously there is no guarantee that a particular application can actually allocate iMaxSockets sockets, since there may be other Windows Sockets applications in use.
iMaxUdpDg	The size in bytes of the largest UDP datagram that can be sent or received by a Windows Sockets application. If the implementation imposes no limit, iMaxUdpDg is zero. In many implementations of Berkeley sockets, there is an implicit limit of 8192 bytes on UDP datagrams (which are fragmented if necessary). A Windows Sockets implementation may impose a limit based, for instance, on the allocation of fragment reassembly buffers. The minimum value of iMaxUdpDg for a compliant Windows Sockets implementation is 512. Note that regardless of the value of iMaxUdpDg, it is inadvisable to attempt to send a broadcast datagram which is larger than the Maximum Transmission Unit (MTU) for the network. (The Windows Sockets API does not provide a mechanism to discover the MTU, but it must be no less than 512 bytes.)
lpVendorInfo	A far pointer to a vendor-specific data structure. The definition of this structure (if supplied) is beyond the scope of this specification.
An application or DLL may call WSAStartup more than once if it needs to obtain the WSAData structure information more than once. However, the wVersionRequired parameter is assumed to be the same on all calls to WSAStartup; that is, an application or DLL cannot change the version of Windows Sockets it expects after the initial call to WSAStartup.

There must be one WSACleanup call corresponding to every WSAStartup call to allow third-party DLLs to make use of a Windows Sockets DLL on behalf of an application. This means, for example, that if an application calls WSAStartup three times, it must call WSACleanup three times. The first two calls to WSACleanup do nothing except decrement an internal counter; the final WSACleanup call for the task does all necessary resource deallocation for the task.

Return Value

WSAStartup returns zero if successful. Otherwise it returns one of the error codes listed below. Note that the normal mechanism whereby the application calls WSAGetLastError to determine the error code cannot be used, since the Windows Sockets DLL may not have established the client data area where the "last error" information is stored.

Notes For Windows Sockets Suppliers

Each Windows Sockets application MUST make a WSAStartup call before issuing any other Windows Sockets API calls. This function can thus be utilized for initialization purposes.

Further issues are discussed in the notes for WSACleanup.

Error Codes

WSASYSNOTREADY	Indicates that the underlying network subsystem is not ready for network communication.
WSAVERNOTSUPPORTED	The version of Windows Sockets API support requested is not provided by this particular Windows Sockets implementation.
WSAEINVAL	The Windows Sockets version specified by the application is not supported by this DLL.
See Also

send, sendto, WSACleanup


WSAUnhookBlockingHook()
WSAUnhookBlockingHook

Description

Restore the default blocking hook function.

 	#include <winsock.h>

 	int PASCAL FAR WSAUnhookBlockingHook ( void );

Remarks

This function removes any previous blocking hook that has been installed and reinstalls the default blocking mechanism.

WSAUnhookBlockingHook will always install the default mechanism, not the previous mechanism. If an application wish to nest blocking hooks - i.e. to establish a temporary blocking hook function and then revert to the previous mechanism (whether the default or one established by an earlier WSASetBlockingHook) - it must save and restore the value returned by WSASetBlockingHook; it cannot use WSAUnhookBlockingHook.

In multithreaded versions of Windows such as Windows NT, there is no default blocking hook. Calling WSAUnhookBlockingHook disables any blocking hook installed by the application and any blocking calls made block the thread which made the call.

Return Value

The return value is 0 if the operation was successful. Otherwise the value SOCKET_ERROR is returned, and a specific error number may be retrieved by calling WSAGetLastError.

Error Codes

WSANOTINITIALISED	A successful WSAStartup must occur before using this API.
See Also

WSASetBlockingHook


Error Codes and Header Files

The following topics list the error codes and header files.

Error Codes

Header Files


Error Codes

The following is a list of possible error codes returned by the WSAGetLastError call, along with their explanations. The error numbers are consistently set across all Windows Sockets-compliant implementations.

Windows Sockets code	Berkeley equivalent	Error	Interpretation
WSAEINTR	EINTR	10004	As in standard C
WSAEBADF	EBADF	10009	As in standard C
WSAEACCES	EACCES	10013	As in standard C
WSAEFAULT	EFAULT	10014	As in standard C
WSAEINVAL	EINVAL	10022	As in standard C
WSAEMFILE	EMFILE	10024	As in standard C
WSAEWOULDBLOCK	EWOULDBLOCK	10035	As in BSD
WSAEINPROGRESS	EINPROGRESS	10036	This error is returned if anyWindows Sockets API function is  called while a blocking function is in progress.
WSAEALREADY	EALREADY	10037	As in BSD
WSAENOTSOCK	ENOTSOCK	10038	As in BSD
WSAEDESTADDRREQ	EDESTADDRREQ	10039	As in BSD
WSAEMSGSIZE	EMSGSIZE	10040	As in BSD
WSAEPROTOTYPE	EPROTOTYPE	10041	As in BSD
WSAENOPROTOOPT	ENOPROTOOPT	10042	As in BSD
WSAEPROTONOSUPPORT	EPROTONOSUPPORT	10043	As in BSD
WSAESOCKTNOSUPPORT	ESOCKTNOSUPPORT	10044	As in BSD
WSAEOPNOTSUPP	EOPNOTSUPP	10045	As in BSD
WSAEPFNOSUPPORT	EPFNOSUPPORT	10046	As in BSD
WSAEAFNOSUPPORT	EAFNOSUPPORT	10047	As in BSD
WSAEADDRINUSE	EADDRINUSE	10048	As in BSD
WSAEADDRNOTAVAIL	EADDRNOTAVAIL	10049	As in BSD
WSAENETDOWN	ENETDOWN	10050	As in BSD. This error may be reported at any time if the Windows Sockets implementation detects an underlying failure.
WSAENETUNREACH	ENETUNREACH	10051	As in BSD
WSAENETRESET	ENETRESET	10052	As in BSD
WSAECONNABORTED	ECONNABORTED	10053	As in BSD
WSAECONNRESET	ECONNRESET	10054	As in BSD
WSAENOBUFS	ENOBUFS	10055	As in BSD
WSAEISCONN	EISCONN	10056	As in BSD
WSAENOTCONN	ENOTCONN	10057	As in BSD
WSAESHUTDOWN	ESHUTDOWN	10058	As in BSD
WSAETOOMANYREFS	ETOOMANYREFS	10059	As in BSD
WSAETIMEDOUT	ETIMEDOUT	10060	As in BSD
WSAECONNREFUSED	ECONNREFUSED	10061	As in BSD
WSAELOOP	ELOOP	10062	As in BSD
WSAENAMETOOLONG	ENAMETOOLONG	10063	As in BSD
WSAEHOSTDOWN	EHOSTDOWN	10064	As in BSD
WSAEHOSTUNREACH	EHOSTUNREACH	10065	As in BSD
WSASYSNOTREADY		10091	Returned by WSAStartup indicating that the network subsystem is unusable.
WSAVERNOTSUPPORTED		10092	Returned by WSAStartup indicating that the Windows SocketsDLL cannot support this app.
WSANOTINITIALISED		10093	Returned by any function except WSAStartup indicating that a successful WSAStartup has not yet been performed.
WSAHOST_NOT_FOUND	HOST_NOT_FOUND	11001	As in BSD.
WSATRY_AGAIN	TRY_AGAIN	11002	As in BSD
WSANO_RECOVERY	NO_RECOVERY	11003	As in BSD
WSANO_DATA	NO_DATA	11004	As in BSD
The first set of definitions is present to resolve contentions between standard C error codes which may be defined inconsistently between various C compilers.

The second set of definitions provides Windows Sockets versions of regular Berkeley Sockets error codes.

The third set of definitions consists of extended Windows Sockets-specific error codes.

The fourth set of errors are returned by Windows Sockets getXbyY and WSAAsyncGetXByY functions, and correspond to the errors which in Berkeley software would be returned in the h_errno variable. They correspond to various failures which may be returned by the Domain Name Service. If the Windows Sockets implementation does not use the DNS, it will use the most appropriate code. In general, a Windows Sockets application should interpret WSAHOST_NOT_FOUND and WSANO_DATA as indicating that the key (name, address, etc.) was not found,, while WSATRY_AGAIN and WSANO_RECOVERY suggest that the name service itself is non-operational.

The error numbers are derived from the winsock.h header file listed in section , and are based on the fact that Windows Sockets error numbers are computed by adding 10000 to the "normal" Berkeley error number.

Note that this table does not include all of the error codes defined in winsock.h. This is because it includes only errors which might reasonably be returned by a Windows Sockets implementation: winsock.h, on the other hand, includes a full set of BSD definitions to ensure compatibility with ported software.


Header Files

Berkeley Header Files

A Windows Sockets supplier who provides a development kit to support the development of Windows Sockets applications must supply a set of vestigial header files with names that match a number of the header files in the Berkeley software distribution. These files are provided for source code compatibility only, and each consists of three lines:

#ifndef _WINSOCKAPI_

#include <winsock.h>

#endif

The header files provided for compatibility are:

netdb.h

arpa/inet.h

sys/time.h

sys/socket.h

netinet/in.h

The file winsock.h contains all of the type and structure definitions, constants, macros, and function prototypes used by the Windows Sockets specification. An application writer may choose to ignore the compatibility headers and include winsock.h in each source file.


Windows Sockets Header File - winsock.h

The winsock.h header file includes a number of types and definitions from the standard Windows header file windows.h. The windows.h in the Windows 3.0 SDK (Software Developer's Kit) lacks a #include guard, so if you need to include windows.h as well as winsock.h, you should define the symbol _INC_WINDOWS before #including winsock.h, as follows:

#include <windows.h>

#define _INC_WINDOWS

#include <winsock.h>

Users of the SDK for Windows 3.1 and later need not do this.

A Windows Sockets DLL vendor MUST NOT make any modifications to this header file which could impact binary compatibility of Windows Sockets applications. The constant values, function parameters and return codes, and the like must remain consistent across all Windows Sockets DLL vendors.

/* WINSOCK.H--definitions to be used with the WINSOCK.DLL

 *

 * This header file corresponds to version 1.1 of the Windows Sockets specification.

 *

 * This file includes parts which are Copyright (c) 1982-1986 Regents

 * of the University of California. All rights reserved. The

 * Berkeley Software License Agreement specifies the terms and

 * conditions for redistribution.

 */

#ifndef _WINSOCKAPI_

#define _WINSOCKAPI_

/*

 * Pull in WINDOWS.H if necessary

 */

#ifndef _INC_WINDOWS

#include <windows.h>

#endif /* _INC_WINDOWS */

/*

 * Basic system type definitions, taken from the BSD file sys/types.h.

 */

typedef unsigned char u_char;

typedef unsigned short u_short;

typedef unsigned int u_int;

typedef unsigned long u_long;

/*

 * The new type to be used in all

 * instances which refer to sockets.

 */

typedef u_int  SOCKET;

/*

 * Select uses arrays of SOCKETs. These macros manipulate such

 * arrays. FD_SETSIZE may be defined by the user before including

 * this file, but the default here should be >= 64.

 *

 * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE

 * INCLUDED IN WINSOCK.H EXACTLY AS SHOWN HERE.

 */

#ifndef FD_SETSIZE

#define FD_SETSIZE 64

#endif /* FD_SETSIZE */

typedef struct fd_set {

 u_short fd_count;  /* how many are SET? */

 SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */

} fd_set;

extern int PASCAL FAR __WSAFDIsSet(SOCKET, fd_set FAR *);

#define FD_CLR(fd, set) do { \

 u_int __i; \

 for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \

 if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \

  while (__i < ((fd_set FAR *)(set))->fd_count-1) { \

  ((fd_set FAR *)(set))->fd_array[__i] = \

   ((fd_set FAR *)(set))->fd_array[__i+1]; \

  __i++; \

  } \

  ((fd_set FAR *)(set))->fd_count--; \

  break; \

 } \

 } \

} while(0)

#define FD_SET(fd, set) do { \

 if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \

 ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=fd;\

} while(0)

#define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)

#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)fd, (fd_set FAR *)set)

/*

 * Structure used in select call, taken from the BSD file sys/time.h.

 */

struct timeval {

 long tv_sec;  /* seconds */

 long tv_usec; /* and microseconds */

};

/*

 * Operations on timevals.

 *

 * NB: timercmp does not work for >= or <=.

 */

#define timerisset(tvp)  ((tvp)->tv_sec || (tvp)->tv_usec)

#define timercmp(tvp, uvp, cmp) \

 ((tvp)->tv_sec cmp (uvp)->tv_sec || \

  (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)

#define timerclear(tvp)  (tvp)->tv_sec = (tvp)->tv_usec = 0

/*

 * Commands for ioctlsocket, taken from the BSD file fcntl.h.

 *

 *

 * Ioctl's have the command encoded in the lower word,

 * and the size of any in or out parameters in the upper

 * word. The high 2 bits of the upper word are used

 * to encode the in/out status of the parameter; for now

 * we restrict parameters to at most 128 bytes.

 */

#define IOCPARM_MASK 0x7f  /* parameters must be < 128 bytes */

#define IOC_VOID 0x20000000 /* no parameters */

#define IOC_OUT  0x40000000 /* copy out parameters */

#define IOC_IN  0x80000000 /* copy in parameters */

#define IOC_INOUT (IOC_IN|IOC_OUT)

     /* 0x20000000 distinguishes new &

      old ioctl's */

#define _IO(x,y) (IOC_VOID|(x<<8)|y)

#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)

#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)

#define FIONREAD _IOR('f', 127, u_long) /* get # bytes to read */

#define FIONBIO _IOW('f', 126, u_long) /* set/clear non-blocking i/o */

#define FIOASYNC _IOW('f', 125, u_long) /* set/clear async i/o */

/* Socket I/O Controls */

#define SIOCSHIWAT _IOW('s', 0, u_long) /* set high watermark */

#define SIOCGHIWAT _IOR('s', 1, u_long) /* get high watermark */

#define SIOCSLOWAT _IOW('s', 2, u_long) /* set low watermark */

#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */

#define SIOCATMARK _IOR('s', 7, u_long) /* at oob mark? */

/*

 * Structures returned by network data base library, taken from the

 * BSD file netdb.h. All addresses are supplied in host order, and

 * returned in network order (suitable for use in system calls).

 */

struct hostent {

 char FAR * h_name;  /* official name of host */

 char FAR * FAR * h_aliases; /* alias list */

 short h_addrtype;  /* host address type */

 short h_length;  /* length of address */

 char FAR * FAR * h_addr_list; /* list of addresses */

#define h_addr h_addr_list[0]  /* address, for backward compat */

};

/*

 * It is assumed here that a network number

 * fits in 32 bits.

 */

struct netent {

 char FAR * n_name;  /* official name of net */

 char FAR * FAR * n_aliases; /* alias list */

 short n_addrtype;  /* net address type */

 u_long n_net;   /* network # */

};

struct servent {

 char FAR * s_name;  /* official service name */

 char FAR * FAR * s_aliases; /* alias list */

 short s_port;   /* port # */

 char FAR * s_proto;  /* protocol to use */

};

struct protoent {

 char FAR * p_name;  /* official protocol name */

 char FAR * FAR * p_aliases; /* alias list */

 short p_proto;  /* protocol # */

};

/*

 * Constants and structures defined by the internet system,

 * Per RFC 790, September 1981, taken from the BSD file netinet/in.h.

 */

/*

 * Protocols

 */

#define IPPROTO_IP  0  /* dummy for IP */

#define IPPROTO_ICMP  1  /* control message protocol */

#define IPPROTO_GGP  2  /* gateway^2 (deprecated) */

#define IPPROTO_TCP  6  /* tcp */

#define IPPROTO_PUP  12  /* pup */

#define IPPROTO_UDP  17  /* user datagram protocol */

#define IPPROTO_IDP  22  /* xns idp */

#define IPPROTO_ND  77  /* UNOFFICIAL net disk proto */

#define IPPROTO_RAW  255  /* raw IP packet */

#define IPPROTO_MAX  256

/*

 * Port/socket numbers: network standard functions

 */

#define IPPORT_ECHO  7

#define IPPORT_DISCARD  9

#define IPPORT_SYSTAT  11

#define IPPORT_DAYTIME  13

#define IPPORT_NETSTAT  15

#define IPPORT_FTP  21

#define IPPORT_TELNET  23

#define IPPORT_SMTP  25

#define IPPORT_TIMESERVER 37

#define IPPORT_NAMESERVER 42

#define IPPORT_WHOIS  43

#define IPPORT_MTP  57

/*

 * Port/socket numbers: host specific functions

 */

#define IPPORT_TFTP  69

#define IPPORT_RJE  77

#define IPPORT_FINGER  79

#define IPPORT_TTYLINK  87

#define IPPORT_SUPDUP  95

/*

 * UNIX TCP sockets

 */

#define IPPORT_EXECSERVER 512

#define IPPORT_LOGINSERVER 513

#define IPPORT_CMDSERVER 514

#define IPPORT_EFSSERVER 520

/*

 * UNIX UDP sockets

 */

#define IPPORT_BIFFUDP  512

#define IPPORT_WHOSERVER 513

#define IPPORT_ROUTESERVER 520

     /* 520+1 also used */

/*

 * Ports < IPPORT_RESERVED are reserved for

 * privileged processes (e.g. root).

 */

#define IPPORT_RESERVED  1024

/*

 * Link numbers

 */

#define IMPLINK_IP  155

#define IMPLINK_LOWEXPER 156

#define IMPLINK_HIGHEXPER 158

/*

 * Internet address (old style... should be updated)

 */

struct in_addr {

 union {

  struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;

  struct { u_short s_w1,s_w2; } S_un_w;

  u_long S_addr;

 } S_un;

#define s_addr S_un.S_addr

    /* can be used for most tcp & ip code */

#define s_host S_un.S_un_b.s_b2

    /* host on imp */

#define s_net S_un.S_un_b.s_b1

    /* network */

#define s_imp S_un.S_un_w.s_w2

    /* imp */

#define s_impno S_un.S_un_b.s_b4

    /* imp # */

#define s_lh S_un.S_un_b.s_b3

    /* logical host */

};

/*

 * Definitions of bits in internet address integers.

 * On subnets, the decomposition of addresses to host and net parts

 * is done according to subnet mask, not the masks here.

 */

#define IN_CLASSA(i)  (((long)(i) & 0x80000000) == 0)

#define IN_CLASSA_NET  0xff000000

#define IN_CLASSA_NSHIFT 24

#define IN_CLASSA_HOST  0x00ffffff

#define IN_CLASSA_MAX  128

#define IN_CLASSB(i)  (((long)(i) & 0xc0000000) == 0x80000000)

#define IN_CLASSB_NET  0xffff0000

#define IN_CLASSB_NSHIFT 16

#define IN_CLASSB_HOST  0x0000ffff

#define IN_CLASSB_MAX  65536

#define IN_CLASSC(i)  (((long)(i) & 0xc0000000) == 0xc0000000)

#define IN_CLASSC_NET  0xffffff00

#define IN_CLASSC_NSHIFT 8

#define IN_CLASSC_HOST  0x000000ff

#define INADDR_ANY  (u_long)0x00000000

#define INADDR_LOOPBACK  0x7f000001

#define INADDR_BROADCAST (u_long)0xffffffff

#define INADDR_NONE  0xffffffff

/*

 * Socket address, internet style.

 */

struct sockaddr_in {

 short sin_family;

 u_short sin_port;

 struct in_addr sin_addr;

 char sin_zero[8];

};

#define WSADESCRIPTION_LEN 256

#define WSASYS_STATUS_LEN 128

typedef struct WSAData {

 WORD   wVersion;

 WORD   wHighVersion;

 char   szDescription[WSADESCRIPTION_LEN+1];

 char   szSystemStatus[WSASYS_STATUS_LEN+1];

 unsigned short  iMaxSockets;

 unsigned short  iMaxUdpDg;

 char FAR *  lpVendorInfo;

} WSADATA;

typedef WSADATA FAR *LPWSADATA;

/*

 * Options for use with [gs]etsockopt at the IP level.

 */

#define IP_OPTIONS 1  /* set/get IP per-packet options */

/*

 * Definitions related to sockets: types, address families, options,

 * taken from the BSD file sys/socket.h.

 */

/*

 * This is used instead of -1, since the

 * SOCKET type is unsigned.

 */

#define INVALID_SOCKET (SOCKET)(~0)

#define SOCKET_ERROR  (-1)

/*

 * Types

 */

#define SOCK_STREAM 1  /* stream socket */

#define SOCK_DGRAM 2  /* datagram socket */

#define SOCK_RAW 3  /* raw-protocol interface */

#define SOCK_RDM 4  /* reliably-delivered message */

#define SOCK_SEQPACKET 5  /* sequenced packet stream */

/*

 * Option flags per-socket.

 */

#define SO_DEBUG 0x0001  /* turn on debugging info recording */

#define SO_ACCEPTCONN 0x0002  /* socket has had listen */

#define SO_REUSEADDR 0x0004  /* allow local address reuse */

#define SO_KEEPALIVE 0x0008  /* keep connections alive */

#define SO_DONTROUTE 0x0010  /* just use interface addresses */

#define SO_BROADCAST 0x0020  /* permit sending of broadcast msgs */

#define SO_USELOOPBACK 0x0040  /* bypass hardware when possible */

#define SO_LINGER 0x0080  /* linger on close if data present */

#define SO_OOBINLINE 0x0100  /* leave received OOB data in line */

#define SO_DONTLINGER (u_int)(~SO_LINGER)

/*

 * Additional options.

 */

#define SO_SNDBUF 0x1001  /* send buffer size */

#define SO_RCVBUF 0x1002  /* receive buffer size */

#define SO_SNDLOWAT 0x1003  /* send low-water mark */

#define SO_RCVLOWAT 0x1004  /* receive low-water mark */

#define SO_SNDTIMEO 0x1005  /* send timeout */

#define SO_RCVTIMEO 0x1006  /* receive timeout */

#define SO_ERROR 0x1007  /* get error status and clear */

#define SO_TYPE  0x1008  /* get socket type */

/*

 * TCP options.

 */

#define TCP_NODELAY 0x0001

/*

 * Address families.

 */

#define AF_UNSPEC 0  /* unspecified */

#define AF_UNIX  1  /* local to host (pipes, portals) */

#define AF_INET  2  /* internetwork: UDP, TCP, etc. */

#define AF_IMPLINK 3  /* arpanet imp addresses */

#define AF_PUP  4  /* pup protocols: e.g. BSP */

#define AF_CHAOS 5  /* mit CHAOS protocols */

#define AF_NS  6  /* XEROX NS protocols */

#define AF_ISO  7  /* ISO protocols */

#define AF_OSI  AF_ISO  /* OSI is ISO */

#define AF_ECMA  8  /* european computer manufacturers */

#define AF_DATAKIT 9  /* datakit protocols */

#define AF_CCITT 10  /* CCITT protocols, X.25 etc */

#define AF_SNA  11  /* IBM SNA */

#define AF_DECnet 12  /* DECnet */

#define AF_DLI  13  /* Direct data link interface */

#define AF_LAT  14  /* LAT */

#define AF_HYLINK 15  /* NSC Hyperchannel */

#define AF_APPLETALK 16  /* AppleTalk */

#define AF_NETBIOS 17  /* NetBios-style addresses */

#define AF_MAX  18

/*

 * Structure used by kernel to store most

 * addresses.

 */

struct sockaddr {

 u_short sa_family;  /* address family */

 char sa_data[14];  /* up to 14 bytes of direct address */

};

/*

 * Structure used by kernel to pass protocol

 * information in raw sockets.

 */

struct sockproto {

 u_short sp_family;  /* address family */

 u_short sp_protocol;  /* protocol */

};

/*

 * Protocol families, same as address families for now.

 */

#define PF_UNSPEC AF_UNSPEC

#define PF_UNIX  AF_UNIX

#define PF_INET  AF_INET

#define PF_IMPLINK AF_IMPLINK

#define PF_PUP  AF_PUP

#define PF_CHAOS AF_CHAOS

#define PF_NS  AF_NS

#define PF_ISO  AF_ISO

#define PF_OSI  AF_OSI

#define PF_ECMA  AF_ECMA

#define PF_DATAKIT AF_DATAKIT

#define PF_CCITT AF_CCITT

#define PF_SNA  AF_SNA

#define PF_DECnet AF_DECnet

#define PF_DLI  AF_DLI

#define PF_LAT  AF_LAT

#define PF_HYLINK AF_HYLINK

#define PF_APPLETALK AF_APPLETALK

#define PF_MAX  AF_MAX

/*

 * Structure used for manipulating linger option.

 */

struct linger {

 u_short l_onoff;  /* option on/off */

 u_short l_linger;  /* linger time */

};

/*

 * Level number for (get/set)sockopt to apply to socket itself.

 */

#define SOL_SOCKET 0xffff  /* options for socket level */

/*

 * Maximum queue length specifiable by listen.

 */

#define SOMAXCONN 5

#define MSG_OOB  0x1  /* process out-of-band data */

#define MSG_PEEK 0x2  /* peek at incoming message */

#define MSG_DONTROUTE 0x4  /* send without using routing tables */

#define MSG_MAXIOVLEN 16

/*

 * Define constant based on rfc883, used by gethostbyxxxx calls.

 */

#define MAXGETHOSTSTRUCT 1024

/*

 * Define flags to be used with the WSAAsyncSelect call.

 */

#define FD_READ  0x01

#define FD_WRITE 0x02

#define FD_OOB  0x04

#define FD_ACCEPT 0x08

#define FD_CONNECT 0x10

#define FD_CLOSE 0x20

/*

 * All Windows Sockets error constants are biased by WSABASEERR from

 * the "normal"

 */

#define WSABASEERR  10000

/*

 * Windows Sockets definitions of regular Microsoft C error constants

 */

#define WSAEINTR  (WSABASEERR+4)

#define WSAEBADF  (WSABASEERR+9)

#define WSAEACCES  (WSABASEERR+13)

#define WSAEFAULT  (WSABASEERR+14)

#define WSAEINVAL  (WSABASEERR+22)

#define WSAEMFILE  (WSABASEERR+24)

/*

 * Windows Sockets definitions of regular Berkeley error constants

 */

#define WSAEWOULDBLOCK  (WSABASEERR+35)

#define WSAEINPROGRESS  (WSABASEERR+36)

#define WSAEALREADY  (WSABASEERR+37)

#define WSAENOTSOCK  (WSABASEERR+38)

#define WSAEDESTADDRREQ  (WSABASEERR+39)

#define WSAEMSGSIZE  (WSABASEERR+40)

#define WSAEPROTOTYPE  (WSABASEERR+41)

#define WSAENOPROTOOPT  (WSABASEERR+42)

#define WSAEPROTONOSUPPORT (WSABASEERR+43)

#define WSAESOCKTNOSUPPORT (WSABASEERR+44)

#define WSAEOPNOTSUPP  (WSABASEERR+45)

#define WSAEPFNOSUPPORT  (WSABASEERR+46)

#define WSAEAFNOSUPPORT  (WSABASEERR+47)

#define WSAEADDRINUSE  (WSABASEERR+48)

#define WSAEADDRNOTAVAIL (WSABASEERR+49)

#define WSAENETDOWN  (WSABASEERR+50)

#define WSAENETUNREACH  (WSABASEERR+51)

#define WSAENETRESET  (WSABASEERR+52)

#define WSAECONNABORTED  (WSABASEERR+53)

#define WSAECONNRESET  (WSABASEERR+54)

#define WSAENOBUFS  (WSABASEERR+55)

#define WSAEISCONN  (WSABASEERR+56)

#define WSAENOTCONN  (WSABASEERR+57)

#define WSAESHUTDOWN  (WSABASEERR+58)

#define WSAETOOMANYREFS  (WSABASEERR+59)

#define WSAETIMEDOUT  (WSABASEERR+60)

#define WSAECONNREFUSED  (WSABASEERR+61)

#define WSAELOOP  (WSABASEERR+62)

#define WSAENAMETOOLONG  (WSABASEERR+63)

#define WSAEHOSTDOWN  (WSABASEERR+64)

#define WSAEHOSTUNREACH  (WSABASEERR+65)

#define WSAENOTEMPTY  (WSABASEERR+66)

#define WSAEPROCLIM  (WSABASEERR+67)

#define WSAEUSERS  (WSABASEERR+68)

#define WSAEDQUOT  (WSABASEERR+69)

#define WSAESTALE  (WSABASEERR+70)

#define WSAEREMOTE  (WSABASEERR+71)

/*

 * Extended Windows Sockets error constant definitions

 */

#define WSASYSNOTREADY  (WSABASEERR+91)

#define WSAVERNOTSUPPORTED (WSABASEERR+92)

#define WSANOTINITIALISED (WSABASEERR+93)

/*

 * Error return codes from gethostbyname and gethostbyaddr

 * (when using the resolver). Note that these errors are

 * retrieved via WSAGetLastError and must therefore follow

 * the rules for avoiding clashes with error numbers from

 * specific implementations or language run-time systems.

 * For this reason the codes are based at WSABASEERR+1001.

 * Note also that [WSA]NO_ADDRESS is defined only for

 * compatibility purposes.

 */

#define h_errno  WSAGetLastError

/* Authoritative Answer: Host not found */

#define WSAHOST_NOT_FOUND (WSABASEERR+1001)

#define HOST_NOT_FOUND  WSAHOST_NOT_FOUND

/* Non-Authoritative: Host not found, or SERVERFAIL */

#define WSATRY_AGAIN  (WSABASEERR+1002)

#define TRY_AGAIN  WSATRY_AGAIN

/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */

#define WSANO_RECOVERY  (WSABASEERR+1003)

#define NO_RECOVERY  WSANO_RECOVERY

/* Valid name, no data record of requested type */

#define WSANO_DATA  (WSABASEERR+1004)

#define NO_DATA   WSANO_DATA

/* no address, look for MX record */

#define WSANO_ADDRESS  WSANO_DATA

#define NO_ADDRESS  WSANO_ADDRESS

/*

 * Windows Sockets errors redefined as regular Berkeley error constants

 */

#define EWOULDBLOCK  WSAEWOULDBLOCK

#define EINPROGRESS  WSAEINPROGRESS

#define EALREADY  WSAEALREADY

#define ENOTSOCK  WSAENOTSOCK

#define EDESTADDRREQ  WSAEDESTADDRREQ

#define EMSGSIZE  WSAEMSGSIZE

#define EPROTOTYPE  WSAEPROTOTYPE

#define ENOPROTOOPT  WSAENOPROTOOPT

#define EPROTONOSUPPORT  WSAEPROTONOSUPPORT

#define ESOCKTNOSUPPORT  WSAESOCKTNOSUPPORT

#define EOPNOTSUPP  WSAEOPNOTSUPP

#define EPFNOSUPPORT  WSAEPFNOSUPPORT

#define EAFNOSUPPORT  WSAEAFNOSUPPORT

#define EADDRINUSE  WSAEADDRINUSE

#define EADDRNOTAVAIL  WSAEADDRNOTAVAIL

#define ENETDOWN  WSAENETDOWN

#define ENETUNREACH  WSAENETUNREACH

#define ENETRESET  WSAENETRESET

#define ECONNABORTED  WSAECONNABORTED

#define ECONNRESET  WSAECONNRESET

#define ENOBUFS   WSAENOBUFS

#define EISCONN   WSAEISCONN

#define ENOTCONN  WSAENOTCONN

#define ESHUTDOWN  WSAESHUTDOWN

#define ETOOMANYREFS  WSAETOOMANYREFS

#define ETIMEDOUT  WSAETIMEDOUT

#define ECONNREFUSED  WSAECONNREFUSED

#define ELOOP   WSAELOOP

#define ENAMETOOLONG  WSAENAMETOOLONG

#define EHOSTDOWN  WSAEHOSTDOWN

#define EHOSTUNREACH  WSAEHOSTUNREACH

#define ENOTEMPTY  WSAENOTEMPTY

#define EPROCLIM  WSAEPROCLIM

#define EUSERS   WSAEUSERS

#define EDQUOT   WSAEDQUOT

#define ESTALE   WSAESTALE

#define EREMOTE   WSAEREMOTE

/* Socket function prototypes */

#ifdef __cplusplus

extern "C" {

#endif

SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,

    int FAR *addrlen);

int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen);

int PASCAL FAR closesocket (SOCKET s);

int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen);

int PASCAL FAR ioctlsocket (SOCKET s, long cmd, u_long FAR *argp);

int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name,

    int FAR * namelen);

int PASCAL FAR getsockname (SOCKET s, struct sockaddr FAR *name,

    int FAR * namelen);

int PASCAL FAR getsockopt (SOCKET s, int level, int optname,

    char FAR * optval, int FAR *optlen);

u_long PASCAL FAR htonl (u_long hostlong);

u_short PASCAL FAR htons (u_short hostshort);

unsigned long PASCAL FAR inet_addr (const char FAR * cp);

char FAR * PASCAL FAR inet_ntoa (struct in_addr in);

int PASCAL FAR listen (SOCKET s, int backlog);

u_long PASCAL FAR ntohl (u_long netlong);

u_short PASCAL FAR ntohs (u_short netshort);

int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags);

int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags,

    struct sockaddr FAR *from, int FAR * fromlen);

int PASCAL FAR select (int nfds, fd_set FAR *readfds, fd_set FAR *writefds,

   fd_set FAR *exceptfds, const struct timeval FAR *timeout);

int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags);

int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags,

   const struct sockaddr FAR *to, int tolen);

int PASCAL FAR setsockopt (SOCKET s, int level, int optname,

    const char FAR * optval, int optlen);

int PASCAL FAR shutdown (SOCKET s, int how);

SOCKET PASCAL FAR socket (int af, int type, int protocol);

/* Database function prototypes */

struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr,

      int len, int type);

struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);

int PASCAL FAR gethostname (char FAR * name, int namelen);

struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto);

struct servent FAR * PASCAL FAR getservbyname(const char FAR * name,

      const char FAR * proto);

struct protoent FAR * PASCAL FAR getprotobynumber(int proto);

struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name);

/* Microsoft Windows Extension function prototypes */

int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);

int PASCAL FAR WSACleanup(void);

void PASCAL FAR WSASetLastError(int iError);

int PASCAL FAR WSAGetLastError(void);

BOOL PASCAL FAR WSAIsBlocking(void);

int PASCAL FAR WSAUnhookBlockingHook(void);

FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc);

int PASCAL FAR WSACancelBlockingCall(void);

HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,

     const char FAR * name,

     const char FAR * proto,

     char FAR * buf, int buflen);

HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,

     const char FAR * proto, char FAR * buf,

     int buflen);

HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,

      const char FAR * name, char FAR * buf,

      int buflen);

HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,

      int number, char FAR * buf,

      int buflen);

HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,

     const char FAR * name, char FAR * buf,

     int buflen);

HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,

     const char FAR * addr, int len, int type,

     const char FAR * buf, int buflen);

int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);

int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,

    long lEvent);

#ifdef __cplusplus

}

#endif

/* Microsoft Windows Extended data types */

typedef struct sockaddr SOCKADDR;

typedef struct sockaddr *PSOCKADDR;

typedef struct sockaddr FAR *LPSOCKADDR;

typedef struct sockaddr_in SOCKADDR_IN;

typedef struct sockaddr_in *PSOCKADDR_IN;

typedef struct sockaddr_in FAR *LPSOCKADDR_IN;

typedef struct linger LINGER;

typedef struct linger *PLINGER;

typedef struct linger FAR *LPLINGER;

typedef struct in_addr IN_ADDR;

typedef struct in_addr *PIN_ADDR;

typedef struct in_addr FAR *LPIN_ADDR;

typedef struct fd_set FD_SET;

typedef struct fd_set *PFD_SET;

typedef struct fd_set FAR *LPFD_SET;

typedef struct hostent HOSTENT;

typedef struct hostent *PHOSTENT;

typedef struct hostent FAR *LPHOSTENT;

typedef struct servent SERVENT;

typedef struct servent *PSERVENT;

typedef struct servent FAR *LPSERVENT;

typedef struct protoent PROTOENT;

typedef struct protoent *PPROTOENT;

typedef struct protoent FAR *LPPROTOENT;

typedef struct timeval TIMEVAL;

typedef struct timeval *PTIMEVAL;

typedef struct timeval FAR *LPTIMEVAL;

/*

 * Windows message parameter composition and decomposition

 * macros.

 *

 * WSAMAKEASYNCREPLY is intended for use by the Windows Sockets implementation

 * when constructing the response to a WSAAsyncGetXByY routine.

 */

#define WSAMAKEASYNCREPLY(buflen,error) MAKELONG(buflen,error)

/*

 * WSAMAKESELECTREPLY is intended for use by the Windows Sockets implementation

 * when constructing the response to WSAAsyncSelect.

 */

#define WSAMAKESELECTREPLY(event,error) MAKELONG(event,error)

/*

 * WSAGETASYNCBUFLEN is intended for use by the Windows Sockets application

 * to extract the buffer length from the lParam in the response

 * to a WSAGetXByY.

 */

#define WSAGETASYNCBUFLEN(lParam)  LOWORD(lParam)

/*

 * WSAGETASYNCERROR is intended for use by the Windows Sockets application

 * to extract the error code from the lParam in the response

 * to a WSAGetXByY.

 */

#define WSAGETASYNCERROR(lParam)  HIWORD(lParam)

/*

 * WSAGETSELECTEVENT is intended for use by the Windows Sockets application

 * to extract the event code from the lParam in the response

 * to a WSAAsyncSelect.

 */

#define WSAGETSELECTEVENT(lParam)  LOWORD(lParam)

/*

 * WSAGETSELECTERROR is intended for use by the Windows Sockets application

 * to extract the error code from the lParam in the response

 * to a WSAAsyncSelect.

 */

#define WSAGETSELECTERROR(lParam)  HIWORD(lParam)

#endif /* _WINSOCKAPI_ */


Notes for Windows Sockets Suppliers

Introduction to Notes for Windows Sockets Suppliers

A Windows Sockets implementation must implement ALL the functionality described in the Windows Sockets documentation. Validation of compliance is discussed in section .

Windows Sockets Version 1.1 implementations must support both TCP and UDP type sockets. An implementation may support raw sockets (of type SOCK_RAW), but their use is deprecated.

Certain APIs documented above have special notes for Windows Sockets implementors. A Windows Sockets implementation should pay special attention to conforming to the API as documented. The Special Notes are provided for assistance and clarification.


Windows Sockets Components

Development Components

The Windows Sockets development components for use by Windows Sockets application developers will be provided by each Windows Sockets supplier. These Windows Sockets development components are:

Component	Description
Windows Sockets Documentation	This document
WINSOCK.LIB file	Windows Sockets API Import Library
WINSOCK.H file	Windows Sockets Header File
NETDB.H file	Berkeley Compatible Header File
ARPA/INET.H file	Berkeley Compatible Header File
SYS/TIME.H file	Berkeley Compatible Header File
SYS/SOCKET.H file	Berkeley Compatible Header File
NETINET/IN.H file	Berkeley Compatible Header File
Run Time Components

The run time component provided by each Windows Sockets supplier is:

Component	Description
WINSOCK.DLL	The Windows Sockets API implementation DLL


Multithreadedness and blocking routines.

Data areas returned by, for example, the getXbyY routines MUST be on a per thread basis.

Note that an application MUST be prevented from making multiple nested Windows Sockets function calls. Only one outstanding function call will be allowed for a particular task. Any Windows Sockets call performed when an existing blocking call is already outstanding will fail with an error code of WSAEINPROGRESS. There are two exceptions to this restriction: WSACancelBlockingCall and WSAIsBlocking may be called at any time. Windows Sockets suppliers should note that although preliminary drafts of this specification indicated that the restriction only applied to blocking function calls, and that it would be permissible to make non-blocking calls while a blocking call was in progress, this is no longer true.

Regarding the implementation of blocking routines, the solution in Windows Sockets is to simulate the blocking mechanism by having each routine call PeekMessage as it waits for the completion of its operation. In anticipation of this, the function WSASetBlockingHook is provided to allow the programmer to define a special routine to be called instead of the default PeekMessage loop. The blocking hook functions are discussed in more detail in , WSASetBlockingHook.


Database Files

The database routines in the getXbyY family (gethostbyaddr, etc.) were originally designed (in the first Berkeley UNIX releases) as mechanisms for looking up information in text databases. A Windows Sockets supplier may choose to employ local files OR a name service to provide some or all of this information. If local files exist, the format of the files must be identical to that used in BSD UNIX, allowing for the differences in text file formats.


FD_ISSET

It is necessary to implement the FD_ISSET Berkeley macro using a supporting function: __WSAFDIsSet. It is the responsibility of a Windows Sockets implementation to make this available as part of the Windows Sockets API. Unlike the other functions exported by a Windows Sockets DLL, however, this function is not intended to be invoked directly by Windows Sockets applications: it should be used only to support the FD_ISSET macro. The source code for this function is listed below:

int FAR

__WSAFDIsSet(SOCKET fd, fd_set FAR *set)

{

 int i = set->fd_count;

 while (i--)

if (set->fd_array[i] == fd)

 return 1;

 return 0;

}


Error Codes

To avoid conflict between various compiler environments Windows Sockets implementations MUST return the error codes listed in the API specification, using the manifest constants beginning with "WSA". The Berkeley-compatible error code definitions are provided solely for compatibility purposes for applications which are being ported from other platforms.


DLL Ordinal Numbers

The winsock.def file for use by every Windows Sockets implementation is as follows. Ordinal values starting at 1000 are reserved for Windows Sockets implementors to use for exporting private interfaces to their DLLs. A Windows Sockets implementation must not use any ordinals 999 and below except for those APIs listed below. An application which wishes to work with any Windows Sockets DLL must use only those routines listed below; using a private export makes an application dependent on a particular Windows Sockets implementation.

;

;  File: winsock.def

; System: MS-Windows 3.x

; Summary: Module definition file for Windows Sockets DLL.

;

LIBRARY  WINSOCK  ; Application's module name

DESCRIPTION 'BSD Socket API for Windows'

EXETYPE  WINDOWS  ; required for all windows applications

STUB  'WINSTUB.EXE' ; generates error message if application

    ; is run without Windows

;CODE can be FIXED in memory because of potential upcalls

CODE  PRELOAD  FIXED

;DATA must be SINGLE and at a FIXED location since this is a DLL

DATA  PRELOAD  FIXED  SINGLE

HEAPSIZE 1024

STACKSIZE 16384

; All functions that will be called by any Windows routine

; must be exported. Any additional exports beyond those defined

; here must have ordinal numbers 1000 or above.

EXPORTS

 accept    @1

 bind    @2

 closesocket   @3

 connect   @4

 getpeername   @5

 getsockname   @6

 getsockopt   @7

 htonl    @8

 htons    @9

 inet_addr   @10

 inet_ntoa   @11

 ioctlsocket   @12

 listen    @13

 ntohl    @14

 ntohs    @15

 recv    @16

 recvfrom   @17

 select    @18

 send    @19

 sendto    @20

 setsockopt   @21

 shutdown   @22

 socket    @23

 gethostbyaddr   @51

 gethostbyname   @52

 getprotobyname   @53

 getprotobynumber  @54

 getservbyname   @55

 getservbyport   @56

 gethostname   @57

 WSAAsyncSelect   @101

 WSAAsyncGetHostByAddr  @102

 WSAAsyncGetHostByName  @103

 WSAAsyncGetProtoByNumber @104

 WSAAsyncGetProtoByName  @105

 WSAAsyncGetServByPort  @106

 WSAAsyncGetServByName  @107

 WSACancelAsyncRequest  @108

 WSASetBlockingHook  @109

 WSAUnhookBlockingHook  @110

 WSAGetLastError  @111

 WSASetLastError  @112

 WSACancelBlockingCall  @113

 WSAIsBlocking   @114

 WSAStartup   @115

 WSACleanup   @116

 __WSAFDIsSet   @151

 WEP    @500 RESIDENTNAME

;eof


Validation Suite

The Windows Sockets API Tester (WSAT) to ensure Windows Sockets compatibility between Windows Sockets DLL implementations is currently in beta test. This beta version includes functionality testing of the Windows Sockets interface and is supported by a comprehensive scripting language. The final version of WSAT will be available in Spring 1993. If you wish to receive the tester or more information on the beta, send email to wsat@microsoft.com.


For Further Reference

This specification is intended to cover the Windows Sockets interface to TCP/IP in detail. Many details of TCP/IP and Windows, however, are intentionally omitted in the interest of brevity, and this specification often assumes background knowledge of these topics. For more information, the following references may be helpful:

Braden, R.[1989], RFC 1122, Requirements for Internet Hosts--Communication Layers, Internet Engineering Task Force.

Comer, D. [1991], Internetworking with TCP/IP Volume I: Principles, Protocols, and Architecture, Prentice Hall, Englewood Cliffs, New Jersey.

Comer, D. and Stevens, D. [1991], Internetworking with TCP/IP Volume II: Design, Implementation, and Internals, Prentice Hall, Englewood Cliffs, New Jersey.

Comer, D. and Stevens, D. [1991], Internetworking with TCP/IP Volume III: Client-Server Programming and Applications, Prentice Hall, Englewood Cliffs, New Jersey.

Leffler, S. et al., An Advanced 4.3BSD Interprocess Communication Tutorial.

Petzold, C. [1992], Programming Windows 3.1, Microsoft Press, Redmond, Washington.

Stevens, W.R. [1990], Unix Network Programming, Prentice Hall, Englewood Cliffs, New Jersey.


Background Information

Legal Status of Windows Sockets

The copyright for the Windows Sockets specification is owned by the specification authors listed on the title page. Permission is granted to redistribute this specification in any form, provided that the contents of the specification are not modified. Windows Sockets implementors are encouraged to include this specification with their product documentation.

The Windows Sockets logo on the title page of this document is meant for use on both Windows Sockets implementations and for applications that use the Windows Sockets interface. Use of the logo is encouraged on packaging, documentation, collateral, and advertising. The logo is available on microdyne.com in pub/winsock as winsock.bmp. The suggested color for the logo's title bar is blue, the electrical socket grey, and the text and outline black.

UNIX is a trademark of Unix System Laboratories, Inc.

VAX is a trademark of Digital Equipment Corporation.

Windows is a trademark of Microsoft Corporation

68000 is a trademark of Motorola, Inc.

NT and Windows/NT are trademarks of Microsoft Corporation.

The Story Behind the Windows Sockets Icon

(by Alistair Banks, Microsoft Corporation)

We thought we'd do a "Wind Sock" at one stage--but you try to get that into 32x32 bits! It would have had to look wavy and colorful, and... well, it just didn't work. Also, our graphics designers have "opinions" about the icons truly representing what they are--people would have thought this was "The colorful wavy tube specification 1.0!"

I tried to explain "API" "Programming Interface" to the artist--we ended up with toolbox icons with little flying windows

Then we came to realise that we should be going after the shortened form of the name, rather the name in full... Windows Sockets... And so we went for that - so she drew (now remember I'm English and you're probably American) "Windows Spanner", a.k.a. a socket wrench. In the U.S. you'd have been talking about the "Windows Socket spec" OK, but in England that would have been translated as "Windows Spanner Spec 1.0" - so we went to Electrical sockets - well the first ones came out looking like "Windows Pignose Spec 1.0"!!!!

So how do you use 32x32, get an international electrical socket! You take the square type (American & English OK, Europe & Australia are too rounded)--you choose the American one, because it's on the wall in front of you (and it's more compact (but less safe, IMHO) and then you turn it upside down, thereby compromising its nationality!

[IMHO = "In My Humble Opinion"--ed.]


EnumProtocols

The EnumProtocols function obtains information about a specified set of network protocols that are active on a local host.

INT EnumProtocols(

LPDWORD  lpdwProtocols,	// points to array of protocol identifiers
LPVOID  lpProtocolBuffer,	// points to buffer to receive protocol information
LPDWORD  lpdwBufferLength	// points to variable that specifies the size of the receiving buffer
);
Parameters

lpdwProtocols

Points to a null-terminated array of protocol identifiers. The EnumProtocols function obtains information about the protocols specified by this array.

If lpdwProtocols is NULL, the function obtains information about all available protocols.

The following protocol identifier values are defined:

Value	Protocol
IPPROTO_TCP	TCP/IP, a connection/stream-oriented protocol
IPPROTO_UDP	User Datagram Protocol (UDP/IP), a connectionless datagram protocol
ISOPROTO_TP4	ISO connection-oriented transport protocol
NSPROTO_IPX	IPX
NSPROTO_SPX	SPX
NSPROTO_SPXII	SPX II
lpProtocolBuffer

Points to a buffer that the function fills with an array of PROTOCOL_INFO data structures.

‹The PROTOCOL_INFO data structure has the following form:

typedef  struct _PROTOCOL_INFO {

    DWORD  dwServiceFlags ;

    INT  iAddressFamily ;

    INT  iMaxSockAddr ;

    INT  iMinSockAddr ;

    INT  iSocketType ;

    INT  iProtocol ;

    DWORD  dwMessageSize ;

    LPTSTR  lpProtocol ;

    DWORD  dwNameSpaces

} PROTOCOL_INFO ;

For a full description of this structure, see its reference page.›

lpdwBufferLength

Points to a variable that, on input, specifies the size, in bytes, of the buffer pointed to by lpProtocolBuffer.

On output, the function sets this variable to the minimum buffer size needed to retrieve all of the requested information. For the function to succeed, the buffer must be at least this size.

Return Value

If the function succeeds, the return value is the number of PROTOCOL_INFO data structures written to the buffer pointed to by lpProtocolBuffer.

If the function fails, the return value is SOCKET_ERROR( − 1). To get extended error information, call GetLastError. GetLastError may return the following extended error value:

Value	Meaning
ERROR_INSUFFICIENT_BUFFER	The buffer pointed to by lpProtocolBuffer was too small to receive all of the relevant PROTOCOL_INFO structures. Call the function with a buffer at least as large as the value returned in *lpdwBufferLength.
Remarks

In the following sample code, the EnumProtocols function obtains information about all protocols that are available on a system. The code then examines each of the protocols in greater detail.

SOCKET

OpenConnection (

PTSTR ServiceName,

PGUID ServiceType,

BOOL Reliable,

BOOL MessageOriented,

BOOL StreamOriented,

BOOL Connectionless,

PINT ProtocolUsed

)

{

// local variables

INT protocols[MAX_PROTOCOLS+1];

BYTE buffer[2048];

DWORD bytesRequired;

INT err;

PPROTOCOL_INFO protocolInfo;

PCSADDR_INFO csaddrInfo;

INT protocolCount;

INT addressCount;

INT i;

DWORD protocolIndex;

SOCKET s;

//

// First look up the protocols installed on this machine.

//

bytesRequired = sizeof(buffer);

err = EnumProtocols( NULL, buffer, &bytesRequired );

if ( err <= 0 ) {

return INVALID_SOCKET;

}

//

// Walk through the available protocols and pick out the ones which

// support the desired characteristics.

//

protocolCount = err;

protocolInfo = (PPROTOCOL_INFO)buffer;

for ( i = 0, protocolIndex = 0;

i < protocolCount && protocolIndex < MAX_PROTOCOLS;

i++, protocolInfo++ ) {

//

// If connection-oriented support is requested, then check if

// supported by this protocol.  We assume here that connection-

// oriented support implies fully reliable service.

//

if ( Reliable ) {

//

// Check to see if the protocol is reliable.  It must

// guarantee both delivery of all data and the order in

// which the data arrives.

//

if ( (protocolInfo->dwServiceFlags &

XP_GUARANTEED_DELIVERY) == 0

||

(protocolInfo->dwServiceFlags &

XP_GUARANTEED_ORDER) == 0 ) {

continue;

}

//

// Check to see that the protocol matches the stream/message

// characteristics requested.

//

if ( StreamOriented &&

(protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED)

!= 0 &&

(protocolInfo->dwServiceFlags & XP_PSEUDO_STREAM)

 == 0 ) {

continue;

}

if ( MessageOriented &&

(protocolInfo->dwServiceFlags & XP_MESSAGE_ORIENTED)

 == 0 ) {

continue;

}

}

else if ( Connectionless ) {

//

// Make sure that this is a connectionless protocol.

//

if ( (protocolInfo->dwServiceFlags & XP_CONNECTIONLESS)

 != 0 ) {

continue;

}

}

//

// This protocol fits all the criteria.  Add it to the list of

// protocols in which we're interested.

//

protocols[protocolIndex++] = protocolInfo->iProtocol;

}

See Also

GetAddressByName, PROTOCOL_INFO


GetAddressByName

The GetAddressByName function queries a name space, or a set of default name spaces, in order to obtain network address information for a specified network service. This process is known as service name resolution. A network service can also use the function to obtain local address information that it can use with the bind function.

INT GetAddressByName(

DWORD  dwNameSpace,	// name space to query for service address information
LPGUID  lpServiceType,	// the type of the service
LPTSTR  lpServiceName,	// the name of the service
LPDWORD  lpdwProtocols,	// points to array of protocol identifiers
DWORD  dwResolution,	// set of bit flags that specify aspects of name resolution
LPSERVICE_ASYNC_INFO  ServiceAsyncInfo,	// reserved for future use, must be NULL
LPVOID  lpCsAddrBuffer,	// points to buffer to receive address information
LPDWORD  lpdwBufferLength,	// points to variable with address buffer size information
LPTSTR  lpAliasBuffer,	// points to buffer to receive alias information
LPDWORD  lpdwAliasBufferLength	// points to variable with alias buffer size information
);
Parameters

dwNameSpace

Specifies the name space, or a set of default name spaces, that the operating system will query for network address information.

Use one of the following constants to specify a name space:

Value	Name Space
NS_DEFAULT	A set of default name spaces. The operating system will query each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. This is the value that most applications should use for dwNameSpace.
NS_DNS
NS_MS
NS_NDS
NS_NETBT
NS_NIS
NS_SAP
NS_STDA
NS_TCPIP_HOSTS
NS_TCPIP_LOCAL
NS_WINS
NS_X500
Most calls to GetAddressByName should use the special value NS_DEFAULT. This lets a client get by with no knowledge of which name spaces are available on an internetwork. The system administrator determines name space access. Name spaces can come and go without the client having to be aware of the changes.

lpServiceType

Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types, and macros for working with them.

lpServiceName

Points to a zero-terminated string that uniquely represents the service name. For example, "MY SNA SERVER".

Setting lpServiceName to NULL is the equivalent of setting dwResolution to RES_SERVICE. The function operates in its second mode, obtaining the local address to which a service of the specified type should bind. The function stores the local address within the LocalAddr member of the CSADDR_INFO structures stored into *lpCsAddrBuffer.

If dwResolution is set to RES_SERVICE, the function ignores the lpServiceName parameter.

If dwNameSpace is set to NS_DNS, *lpServiceName is the name of the host.

lpdwProtocols

Points to a zero-terminated array of protocol identifiers. The function restricts a name resolution attempt to name space providers that offer these protocols. This lets the caller limit the scope of the search.

If lpdwProtocols is NULL, the function obtains information on all available protocols.

dwResolution

A set of bit flags that specify aspects of the service name resolution process. The following bit flags are defined:

Value	Meaning
RES_SERVICE	If this flag is set, the function obtains the address to which a service of the specified type should bind. This is the equivalent of setting lpServiceName to NULL. If this flag is clear, normal name resolution occurs.
RES_FIND_MULTIPLE	If this flag is set, the operating system performs an extensive search of all name spaces for the service. It will ask every appropriate name space to resolve the service name. If this flag is clear, the operating system stops looking for service addresses as soon as one is found.
RES_SOFT_SEARCH	This flag is valid if the name space supports multiple levels of searching. If this flag is valid and set, the operating system performs a simple and quick search of the name space. This is useful if an application only needs to obtain easy-to-find addresses for the service. If this flag is valid and clear, the operating system performs a more extensive search of the name space.
lpServiceAsyncInfo

Reserved for future use; must be set to NULL.

lpCsAddrBuffer

Points to a buffer to receive one or more CSADDR_INFO data structures. The number of structures written to the buffer depends on the amount of information found in the resolution attempt. You should assume that multiple structures will be written, although in many cases there will only be one.

lpdwBufferLength

Points to a variable that, upon input, specifies the size, in bytes, of the buffer pointed to by lpCsAddrBuffer.

Upon output, this variable contains the total number of bytes required to store the array of CSADDR_INFO structures. If this value is less than or equal to the input value of *lpdwBufferLength, and the function is successful, this is the number of bytes actually stored in the buffer. If this value is greater than the input value of *lpdwBufferLength, the buffer was too small, and the output value of *lpdwBufferLength is the minimal required buffer size.

lpAliasBuffer

Points to a buffer to receive alias information for the network service.

If a name space supports aliases, the function stores an array of zero-terminated name strings into the buffer pointed to by lpAliasBuffer. There is a double zero-terminator at the end of the list. The first name in the array is the service's primary name. Names that follow are aliases. An example of a name space that supports aliases is DNS.

If a name space does not support aliases, it stores a double zero-terminator into the buffer.

This parameter is optional, and can be set to NULL.

lpdwAliasBufferLength

Points to a variable that, upon input, specifies the size, in bytes, of the buffer pointed to by lpAliasBuffer.

Upon output, this variable contains the total number of bytes required to store the array of name strings. If this value is less than or equal to the input value of *lpdwAliasBufferLength, and the function is successful, this is the number of bytes actually stored in the buffer. If this value is greater than the input value of *lpdwAliasBufferLength, the buffer was too small, and the output value of *lpdwAliasBufferLength is the minimal required buffer size.

If lpAliasBuffer is NULL, lpdwAliasBufferLength is meaningless and can also be NULL.

Return Value

If the function succeeds, the return value is the number of CSADDR_INFO data structures written to the buffer pointed to by lpCsAddrBuffer.

If the function fails, the return value is SOCKET_ERROR( − 1). To get extended error information, call GetLastError. GetLastError may return the following extended error value:

Value	Meaning
ERROR_INSUFFICIENT_BUFFER	The buffer pointed to by lpCsAddrBuffer was too small to receive all of the relevant CSADDR_INFO structures. Call the function with a buffer at least as large as the value returned in *lpdwBufferLength.
Remarks

This function is a more powerful version of the Windows Sockets function gethostbyname The GetAddressByName function works with multiple name services.

The GetAddressByName function lets a client obtain a Windows Sockets address for a network service. The client specifies the service of interest by its service type and service name.

Many name services support a default prefix or suffix that the name service provider considers when resolving service names. For example, in the DNS name space, if a domain is named "nt.microsoft.com", and "ftp millikan" is provided as input, the DNS software fails to resolve "millikan", but successfully resolves "millikan.nt.microsoft.com".

Note that the GetAddressByName function can search for a service address in two ways: within a particular name space, or within a set of default name spaces. Using a default name space, an administrator can specify that certain name spaces will be searched for service addresses only if specified by name. An administrator or name space setup program can also control the ordering of name space searches.

See Also

gethostbyname, CSADDR_INFO


GetNameByType

INT GetNameByType(pServiceType, lpServiceName, lpdwBufferLength)
PGUID  pServiceType, 	// points to network service type GUID
LPTSTR  lpServiceName, 	// points to buffer to receive name of network service
LPDWORD  lpdwBufferLength  	// points to variable that specifies buffer size

The GetNameByType function obtains the name of a network service. The network service is specified by its service type.

Parameters

pServiceType

Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types, and macros for working with them.

lpServiceName

Points to a buffer to receive a zero-terminated string that uniquely represents the name of the network service.

lpdwBufferLength

Points to a variable that, on input, specifies the size of the buffer pointed to by lpServiceName. On output, the variable contains the actual size of the service name string.

Return Value

If the function succeeds, the return value is not SOCKET_ERROR( − 1).

If the function fails, the return value is SOCKET_ERROR( − 1). To get extended error information, call GetLastError.

See Also

GetTypeByName


GetService

The GetService function obtains information about a network service in the context of a set of default name spaces or a specified name space. The network service is specified by its type and name. The information about the service is obtained as a set of NS_SERVICE_INFO data structures.

INT GetService(

DWORD  dwNameSpace,	// specifies name space or spaces to search
PGUID  pServiceType,	// points to GUID service type
LPTSTR  lpServiceName,	// points to service name
DWORD  dwProperties,	// specifies service information to be obtained
LPVOID  lpBuffer,	// points to buffer to receive service information
LPDWORD  lpdwBufferSize,	// points to size of buffer, size of service information
LPSERVICE_ASYNC_INFO  lpServiceAsyncInfo	// reserved for future use, must be NULL
);
Parameters

dwNameSpace

Specifies the name space, or a set of default name spaces, that the operating system will query for information about the specified network service.

Use one of the following constants to specify a name space:

Value	Name Space
NS_CAIRO
NS_DEFAULT	A set of default name spaces. The operating system will query each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS
NS_MS
NS_NDS
NS_NETBT
NS_NIS
NS_SAP
NS_STDA
NS_TCPIP_HOSTS
NS_TCPIP_LOCAL
NS_WINS
NS_X500
Most calls to GetService should use the special value NS_DEFAULT. This lets a client get by with no knowledge of which name spaces are available on an internetwork. The system administrator determines name space access. Name spaces can come and go without the client having to be aware of the changes.

pServiceType

Points to a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGRUID.H includes GUIDS from many well known services within the DNS and SAP name spaces.

lpServiceName

Points to a zero-terminated string that uniquely represents the service name. For example, "MY SNA SERVER".

dwProperties

A set of bit-flags that specify the service information that the function obtains. Each of these bit flag constants, other than PROP_ALL, corresponds to a particular member of the SERVICE_INFO data structure. If the flag is set, the function puts information into the corresponding member of the data structures stored in *lpBuffer. The following bit flags are defined:

Value	Name Space
PROP_COMMENT	If this flag is set, the function stores data in the lpComment member of the data structures stored in *lpBuffer.
PROP_LOCALE	If this flag is set, the function stores data in the lpLocale member of the data structures stored in *lpBuffer.
PROP_DISPLAY_HINT	If this flag is set, the function stores data in the dwDisplayHint member of the data structures stored in *lpBuffer.
PROP_VERSION	If this flag is set, the function stores data in the dwVersion member of the data structures stored in *lpBuffer.
PROP_START_TIME	If this flag is set, the function stores data in the dwTime member of the data structures stored in *lpBuffer.
PROP_MACHINE	If this flag is set, the function stores data in the lpMachineName member of the data structures stored in *lpBuffer.
PROP_ADDRESSES	If this flag is set, the function stores data in the lpServiceAddress member of the data structures stored in *lpBuffer.
PROP_SD	If this flag is set, the function stores data in the ServiceSpecificInfo member of the data structures stored in *lpBuffer.
PROP_ALL	If this flag is set, the function stores data in all of the members of the data structures stored in *lpBuffer.
lpBuffer

Points to a buffer to receive an array of NS_SERVICE_INFO structures and associated service information. Each NS_SERVICE_INFO structure contains service information in the context of a particular name space. Note that if dwNameSpace is NS_DEFAULT, the function stores more than one structure into the buffer; otherwise, just one structure is stored.

Each NS_SERVICE_INFO structure contains a SERVICE_INFO structure. The members of these SERVICE_INFO structures will contain valid data based on the bit-flags that are set in the dwProperties parameter. If a member's corresponding bit-flag is not set in dwProperties, the member's value is undefined.

The function stores the NS_SERVICE_INFO structures in a consecutive array, starting at the beginning of the buffer. The pointers in the contained SERVICE_INFO structures point to information that is stored in the buffer between the end of the NS_SERVICE_INFO structures and the end of the buffer.

lpdwBufferSize

Points to a variable that, on input, contains the size, in bytes, of the buffer pointed to by lpBuffer. On output, this variable contains the number of bytes required to store the requested information. If this output value is greater than the input value, the function has failed due to insufficient buffer size.

lpServiceAsyncInfo

This parameter is reserved for future use. It must be set to NULL.

Return Value

If the function succeeds, the return value is the number of NS_SERVICE_INFO structures stored in *lpBuffer. Zero indicates that no structures were stored.

If the function fails, the return value is SOCKET_ERROR( − 1). To get extended error information, call GetLastError. GetLastError may return one of the following extended error values:

Value	Meaning
ERROR_INSUFFICIENT_BUFFER	The buffer pointed to by lpBuffer is too small to receive all of the requested information. Call the function with a buffer at least as large as the value returned in *lpdwBufferSize.
ERROR_SERVICE_NOT_FOUND	The specified service was not found, or the specified name space is not in use. The function return value is zero in this case.
See Also

SetService, NS_SERVICE_INFO, SERVICE_INFO


GetTypeByName

The GetTypeByName function obtains a service type GUID for a network service specified by name.

INT GetTypeByName(

LPTSTR  lpServiceName,	// points to the name of the network service
PGUID  pServiceType	// points to a variable to receive network service type
);
Parameters

lpServiceName

Points to a zero-terminated string that uniquely represents the name of the service. For example, "MY SNA SERVER".

pServiceType

Points to a variable to receive a globally unique identifier (GUID) that specifies the type of the network service. The header file SVCGUID.H includes definitions of several GUID service types and macros for working with them.

Return Value

If the function succeeds, the return value is zero.

If the function fails, the return value is SOCKET_ERROR( − 1). To get extended error information, call GetLastError. GetLastError may return the following extended error value:

Value	Meaning
ERROR_SERVICE_DOES_NOT_EXIST	The specified service type is unknown.
See Also

GetNameByType


SetService

The SetService function registers or deregisters a network service within one or more name spaces. The function can also add or remove a network service type within one or more name spaces.

INT SetService(

DWORD  dwNameSpace,	// specifies name space(s) to operate within
DWORD  dwOperation,	// specifies operation to perform
DWORD  dwFlags,	// set of bit flags that modify function operation
LPSERVICEINFO  lpServiceInfo,	// points to structure containing service information
LPSERVICE_ASYNC_INFO  lpServiceAsyncInfo,	// reserved for future use, must be NULL
LPDWORD  lpdwStatusFlags	// points to set of status bit flags
);
Parameters

dwNameSpace

Specifies the name space, or a set of default name spaces, within which the function will operate.

Use one of the following constants to specify a name space:

Value	Name Space
NS_DEFAULT	A set of default name spaces. The function will operate on each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS
NS_MS
NS_NDS
NS_NETBT
NS_NIS
NS_SAP
NS_STDA
NS_TCPIP_HOSTS
NS_TCPIP_LOCAL
NS_WINS
NS_X500
dwOperation

Specifies the operation that the function will perform. Use one of the following values to specify an operation:

Value	Meaning
SERVICE_REGISTER	Register the network service with the name space. This operation may be used with the SERVICE_FLAG_DEFER and SERVICE_FLAG_HARD bit flags.
SERVICE_DEREGISTER	Deregister the network service from the name space. This operation can be used with the SERVICE_FLAG_DEFER and SERVICE_FLAG_HARD bit flags.
SERVICE_FLUSH	Perform any operation that was called with the SERVICE_FLAG_DEFER bit flag set to one.
SERVICE_ADD_TYPE	Add a service type to the name space.  For this operation, use the ServiceSpecificInfo member of the SERVICE_INFO structure pointed to by lpServiceInfo to pass a SERVICE_TYPE_INFO_ABS structure. You must also set the ServiceType member of the SERVICE_INFO structure. Other SERVICE_INFO members are ignored.
SERVICE_DELETE_TYPE	Remove a service type, added by a previous call specifying the SERVICE_ADD_TYPE operation,  from the name space.
dwFlags

A set of bit flags that modify the function's operation. You can set one or more of the following bit flags:

Value	Name Space
SERVICE_FLAG_DEFER	This bit flag is valid only if the operation is SERVICE_REGISTER or SERVICE_DEREGISTER. If this bit flag is one, and it is valid, the name-space provider should defer the registration or deregistration operation until a SERVICE_FLUSH operation is requested.
SERVICE_FLAG_HARD	This bit flag is valid only if the operation is SERVICE_REGISTER or SERVICE_DEREGISTER. If this bit flag is one, and it is valid, the name-space provider updates any relevant persistent store information when the operation is performed.  For example: If the operation involves deregistration in a name space that uses a persistent store, the name-space provider would remove the relevant persistent store information.
lpService_Info

Points to a SERVICE_INFO structure that contains information about the network service or service type.

lpServiceAsyncInfo

This parameter is reserved for future use. It must be set to NULL.

lpdwStatusFlags

A set of bit flags that receive function status information. The following bit flag is defined:

Value	Meaning
SET_SERVICE_PARTIAL_SUCCESS	One or more name-space providers were unable to successfully perform the requested operation.
Return Value

If the function succeeds, the return value is not SOCKET_ERROR.

If the function fails, the return value is SOCKET_ERROR. To get extended error information, call GetLastError. GetLastError may return the following extended error value:

Value	Meaning
ERROR_ALREADY_REGISTERED	The function tried to register a service that was already registered.
See Also

GetService, SERVICE_INFO, SERVICE_TYPE_INFO_ABS


BLOB

typedef struct _BLOB {

    ULONG   cbSize ;

    BYTE    *pBlobData ;

} BLOB;

A BLOB structure contains information about a block of data.

Members

cbSize

Specifies the size in bytes of the block of data pointed to by pBlobData

Addresses

Points to a block of data.

Remarks

The structure name BLOB comes from the acronym BLOB, which stands for "Binary Large OBject".

Note that this structure description says nothing about the nature of the data pointed to by pBlobData.

See Also

SERVICE_INFO


CSADDR_INFO

typedef struct _CSADDR_INFO {

    SOCKET_ADDRESS	    LocalAddr ;

    SOCKET_ADDRESS    	RemoteAddr ;

    INT	    iSocketType ;

    INT	    iProtocol ;

} CSADDR_INFO ;

The CSADDR_INFO structure contains Windows Sockets address information for a network service or name space provider. The GetAddressByName function obtains Windows Sockets address information using CSADDR_INFO structures.

LocalAddr

Specifies a Windows Sockets local address.

In a client application, pass this address to the bind function to obtain access to a network service.

In a network service, pass this address to the bind function so that the service is bound to the appropriate local address.

RemoteAddr

Specifies a Windows Sockets remote address. There are several uses for this remote address:

•	You can use this remote address to connect to the service via the connect function. This is useful if an application performs send/receive operations that involve connection-oriented protocols.

•	You can use this remote address with the sendto function when you are communicating over a connectionless (datagram) protocol. If you are using a connectionless protocol, such as UDP, sendto is typically the way you pass data to the remote system.

iSocketType

Specifies the type of the Windows socket. The following socket types are defined in winsock.h :

Value	Socket Type
SOCK_STREAM	Stream.This is a protocol that sends data as a stream of bytes, with no message boundaries.
SOCK_DGRAM	Datagram. This is a connectionless protocol. There is no virtual circuit setup. There are typically no reliability guarantees. Services use recvfrom to obtain datagrams. The listen and accept functions do not work with datagrams.
SOCK_RDM	Reliably-Delivered Message. This is a protocol that preserves message boundaries in data.
SOCK_SEQPACKET	Sequenced packet stream. This is a protocol that is essentially the same as SOCK_RDM.
iProtocol

Specifies a value to pass as the protocol parameter to the socket function to open a socket for this service.

See Also

bind, connect, GetAddressByName, receive, send, sendto


NS_SERVICE_INFO

typedef struct _NS_SERVICE_INFO {

    DWORD   dwNameSpace;

    SERVICE_INFO ServiceInfo;

} NS_SERVICE_INFO;

The NS_SERVICE_INFO structure contains information about a network service or a network service type in the context of a specified name space, or a set of default name spaces.

Members

dwNameSpace

Specifies the name space or a set of default name spaces to which this service information applies.

Use one of the following constant values to specify a name space:

Value	Name Space
NS_DEFAULT	A set of default name spaces. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set.
NS_DNS
NS_MS
NS_NDS
NS_NETBT
NS_NIS
NS_SAP
NS_STDA
NS_TCPIP_HOSTS
NS_TCPIP_LOCAL
NS_WINS
NS_X500
ServiceInfo

A SERVICE_INFO structure that contains information about a network service or network service type.

See Also

GetService, SetService, SERVICE_INFO


PROTOCOL_INFO

typedef  struct _PROTOCOL_INFO {

    DWORD  dwServiceFlags ;

    INT  iAddressFamily ;

    INT  iMaxSockAddr ;

    INT  iMinSockAddr ;

    INT  iSocketType ;

    INT  iProtocol ;

    DWORD  dwMessageSize ;

    LPTSTR  lpProtocol ;

} PROTOCOL_INFO ;

The PROTOCOL_INFO structure contains information about a protocol.

Members

dwServiceFlags

A set of bit flags that specify the services provided by the protocol. One or more of the following bit flags may be set:

Value	Meaning
XP_CONNECTIONLESS	If this flag is set, the protocol providesconnectionless (datagram) service. If this flag is clear, the protocol provides connection-oriented data transfer.
XP_GUARANTEED_DELIVERY	If this flag is set, the protocol guarantees that all data sent will reach the intended destination. If this flag is clear, there is no such guarantee.
XP_GUARANTEED_ORDER	If this flag is set, the protocol guarantees that data will arrive in the order in which it was sent. Note that this characteristic does not guarantee delivery of the data, but guarantees only its order. If this flag is clear, the order of data sent is not guaranteed.
XP_MESSAGE_ORIENTED	If this flag is set, the protocol is message-oriented. A message-oriented protocol honors message boundaries. If this flag is clear, the protocol is stream-oriented, and the concept of message boundaries is irrelevant.
XP_PSEUDO_STREAM	If this flag is set, the protocol is a message-oriented protocol that ignores message boundaries for all receive operations.  This optional capability is useful when you do not want the protocol to frame messages. An application that requires stream-oriented characteristics can open a socket with type SOCK_STREAM for transport protocols that support this functionality, regardless of the value of iSocketType.
XP_GRACEFUL_CLOSE	If this flag is set, the protocol supports two-phase close operations, also known as "graceful" close operations. If this flag is clear, the protocol supports only abortive close operations.
XP_EXPEDITED_DATA	If this flag is set, the protocol supports expedited data, also known as "urgent data."
XP_CONNECT_DATA	If this flag is set, the protocol supports connect data.
XP_DISCONNECT_DATA	If this flag is set, the protocol supports disconnect data.
XP_SUPPORTS_BROADCAST	If this flag is set, the protocol supports a broadcast mechanism.
XP_SUPPORTS_MULTICAST	If this flag is set, the protocol supports a multicast mechanism.
XP_BANDWIDTH_ALLOCATION	If this flag is set, the protocol supports a mechanism for allocating a guaranteed bandwidth to an application.
XP_FRAGMENTATION	If this flag isset, the protocol supports message fragmentation; physical network MTU is hidden from applications.
XP_ENCRYPTS	If this flag is set, the protocol supports data encryption.
iAddressFamily

Specifies the value to pass as the af parameter when you call the socket function to open a socket for the protocol. This address family value uniquely defines the structure of Protocol addresses, also known as SOCKADDRs, used by the protocol.

iMaxSockAddr

Specifies the maximum length of a socket address supported by the protocol.

iMinSockAddr

Specifies the minimum length of a socket address supported by the protocol.

iSocketType

Specifies the value to pass as the type parameter when you call the socket function to open a socket for the protocol.

Note that if XP_PSEUDO_STREAM is set in dwServiceFlags, the application can specify SOCK_STREAM as the type parameter to socket, regardless of the value of iSocketType.

iProtocol

Specifies the value to pass as the protocol parameter when you call the socket function to open a socket for the protocol.

dwMessageSize

Specifies the maximum message size supported by the protocol. This is the maximum size of a message that can be sent from or received by the host. For protocols that do not support message framing, the actual maximum size of a message that can be sent to a given address may be less than this value.

The following special message size values are defined:

Value	Meaning
0	The protocol is stream-oriented; the concept of message size is not relevant.
0xFFFFFFFF	The protocol is message-oriented, but there is no maximum message size.
lpProtocol

Points to a zero-terminated string that supplies a name for the protocol; for example, "SPX2."

See Also

EnumProtocols, socket


SERVICE_ADDRESS

typedef struct _SERVICE_ADDRESS {

    DWORD   dwAddressType;

    DWORD   dwAddressFlags;

    DWORD   dwAddressLength;

    DWORD   dwPrincipalLength;

    BYTE   *lpAddress;

    BYTE   *lpPrincipal;

} SERVICE_ADDRESS;

The SERVICE_ADDRESS structure contains address information for a service. The structure can accomodate many types of interprocess communications (IPC) mechanisms and their address forms, including remote procedure calls (RPCs), named pipes, and sockets.

Members

dwAddressType

Specifies the address family that the socket address pointed to by lpAddress belongs to.

dwAddressFlags

A set of bit flags that specify properties of the address. The following bit flags are defined:

Value	Meaning
SERVICE_ADDRESS_FLAG_RPC_CN	If this bit flag is set, the service supports connection-oriented RPC over this transport protocol.
SERVICE_ADDRESS_FLAG_RPC_DG	If this bit flag is set, the service supports datagram-oriented RPC over this transport protocol.
SERVICE_ADDRESS_FLAG_RPC_NB	If this bit flag is set, the service supports NetBIOS RPC over this transport protocol.
dwAddressLength

Specifies the size, in bytes, of the address.

dwPrincipalLength

This member is reserved for future use. It must be zero.

lpAddress

Points to a socket address of the appropriate type.

lpPrincipal

This member is reserved for future use. It must be NULL.

See Also

SERVICE_ADDRESSES, SERVICE_INFO


SERVICE_ADDRESSES

typedef struct _SERVICE_ADDRESSES {

    DWORD   dwAddressCount;

    SERVICE_ADDRESS   Addresses[1];

} SERVICE_ADDRESSES;

The SERVICE_ADDRESSES structure contains an array of SERVICE_ADDRESS data structures.

Members

dwAddressCount

Specifies the number of SERVICE_ADDRESS structures in the Addresses array.

Addresses

An array of SERVICE_ADDRESS data structures. Each SERVICE_ADDRESS structure contains information about a network service address.

See Also

SERVICE_ADDRESS, SERVICE_INFO


SERVICE_INFO

typedef struct _SERVICE_INFO {

    LPGUID   lpServiceType ;

    LPTSTR   lpServiceName ;

    LPTSTR   lpComment ;

    LPTSTR   lpLocale ;

    DWORD    dwDisplayHint ;

    DWORD    dwVersion ;

    DWORD    dwTime ;

    LPTSTR   lpMachineName ;

    LPSERVICE_ADDRESSES lpServiceAddress ;

    BLOB ServiceSpecificInfo ;

} SERVICE_INFO;

The SERVICE_INFO structure contains information about a network service or a network service type.

Members

lpServiceType

Points to a GUID that is the type of the network service.

lpServiceName

Points to a zero-terminated string that is the name of the network service.

If you are calling the SetService function with the dwNameSpace parameter set to NS_DEFAULT, the network service name must be a common name A common name is what the network service is commonly known as. An example of a common name for a network service is "My SQL Server".

If you are calling the SetService function with the dwNameSpace parameter set to a specific service name, the network service name can be a common name or a distinguished name. A distinguished name distinguishes the service to a unique location with a directory service. An example of a distinguished name for a network service is "MS\\SYS\\NT\\DEV\\My SQL Server". The

lpComment

Points to a zero-terminated string that is a comment or description for the network service. For example, "Used for development upgrades."

lpLocale

Points to a zero-terminated string that contains locale information.

dwDisplayHint

Specifies a hint as to how to display the network service in a network browsing user interface. This can be one of the following values:

Value	Meaning
RESOURCEDISPLAYTYPE_DOMAIN	Display the network service as a domain.
RESOURCEDISPLAYTYPE_FILE	Display the network service as a file.
RESOURCEDISPLAYTYPE_GENERIC	The method used to display the object does not matter.
RESOURCEDISPLAYTYPE_GROUP	Display the network service as a group.
RESOURCEDISPLAYTYPE_SERVER	Display the network service as a server.
RESOURCEDISPLAYTYPE_SHARE	Display the network service as a sharepoint.
RESOURCEDISPLAYTYPE_TREE	Display the network service as a tree.
dwVersion

Specifies version information for the network service. The high word of this value specifies a major version number. The low word of this value specifies a minor version number.

dwTime

This member is reserved for future use. It must be set to zero.

lpMachineName

Points to a zero-terminated string that is the name of the computer on which the network service is running.

lpServiceAddress

Points to a SERVICE_ADDRESSES structure that contains an array of SERVICE_ADDRESS structures. Each SERVICE_ADDRESS structure contains information about a network service address.

A network service can call the getsockname function to determine the local address of the system.

ServiceSpecificInfo

A BLOB structure that specifies service-defined information.

The BLOB structure has the following form:

typedef struct _BLOB {

    ULONG cbSize ;

    BYTE *pBlobData ;

} BLOB, *LPBLOB ;

For a full description of this structure, refer to its reference page.

Note that, in general, the data pointed to by the BLOB structure's pBlobData member must not contain any pointers. That is because only the network service knows the format of the data; copying the data without such knowledge would lead to pointer invalidation. If the data pointed to by pBlobData contains variable-sized elements, offsets from pBlobData can be used to indicate the location of those elements. There is one exception to this general rule: when pBlobData points to a SERVICE_TYPE_INFO_ABS structure. This is possible because both the SERVICE_TYPE_INFO_ABS structure, and any SERVICE_TYPE_VALUE_ABS structures it contains are predefined, and thus their formats are known to the operating system.

See Also

GetService, SetService, BLOB, SERVICE_ADDRESS, SERVICE_ADDRESSES, NS_SERVICE_INFO


SERVICE_TYPE_INFO_ABS

typedef struct _SERVICE_TYPE_INFO_ABS {

    LPTSTR   lpTypeName;

    DWORD   dwValueCount;

    SERVICE_TYPE_VALUE_ABS Values[1];

} SERVICE_TYPE_INFO_ABS

The SERVICE_TYPE_INFO_ABS structure contains information about a network service type. You use a SERVICE_TYPE_INFO_ABS structure to add a network service type to a name space.

Members

lpTypeName

Points to a zero-terminated string that is the name of the network service type.  This name is the same in all name spaces, and is used by the GetTypeByName and GetNameByType functions.

dwValueCount

Specifies the number of SERVICE_TYPE_VALUE_ABS structures in the Values member array that follows dwValueCount.

Values[1]

An array of SERVICE_TYPE_VALUE_ABS structures.

Each of these structures contains information about a service type value that the operating system or network service may need when an instance of this network service type is registered with a name space.

The information in these structures may be specific to a name-space. For example, if a network service uses the SAP name space, but does not have a GUID that contains the SAP identifier (SAPID), it defines the SAPID in a SERVICE_TYPE_VALUE_ABS structure.

Remarks

When you use the SetService function to add a network service type to a name space, the SERVICE_TYPE_INFO_ABS structure is passed as the ServiceSpecificInfo BLOB member of a SERVICE_INFO structure. Although the ServiceSpecificInfo member generally should not contain pointers, an exception is made in the case of the SERVICE_TYPE_INFO_ABS and SERVICE_TYPE_VALUE_ABS structures.

See Also

SetService, SERVICE_INFO, SERVICE_TYPE_VALUE_ABS


SERVICE_TYPE_VALUE_ABS

typedef struct _SERVICE_TYPE_VALUE_ABS {

    DWORD   dwNameSpace ;

    DWORD   dwValueType ;

    DWORD   dwValueSize ;

    LPTSTR   lpValueName ;

    PVOID   lpValue ;

} SERVICE_TYPE_VALUE_ABS

The SERVICE_TYPE_VALUE_ABS structure contains information about a network-service type value. This information may be specific to a name space.

Members

dwNameSpace

Specifies the name space, or a set of default name spaces, for which the network service type value is intended . Name-space providers will look only at values intended for their name space.

Use one of the following constants to specify a name space:

Value	Name Space
NS_DEFAULT	A set of default name spaces. The function will operate on each name space within this set. The set of default name spaces typically includes all the name spaces installed on the system. System administrators, however, can exclude particular name spaces from the set. NS_DEFAULT is the value that most applications should use for dwNameSpace.
NS_DNS
NS_MS
NS_NDS
NS_NETBT
NS_NIS
NS_SAP
NS_STDA
NS_TCPIP_HOSTS
NS_TCPIP_LOCAL
NS_WINS
NS_X500
dwValueType

Specifies the type of the value data. You can specify one of the following types:

Value	Meaning
REG_BINARY	Binary data in any form.
REG_DWORD	A 32-bit number.
REG_MULTI_SZ	An array of null-terminated strings, terminated by two null characters.
REG_SZ	A null-terminated string.
dwValueSize

Specifies the size, in bytes, of the value data. In the case of REG_SZ and REG_MULTI_SZ string data, the terminating characters are counted as part of the size.

lpValueName

Points to a zero-terminated string that is the name of the value. This name is specific to a  name space.

Several commonly used value name strings are associated with defined constants. These name strings include the following:

Constant	Name String
SERVICE_TYPE_VALUE_SAPID	"SapId"
SERVICE_TYPE_VALUE_CONN	"ConnectionOriented"
SERVICE_TYPE_VALUE_TCPPORT	"TcpPort"
SERVICE_TYPE_VALUE_UDPPORT	"UdpPort"
lpValue

Points to the value data.

Remarks

When you use the SetService function to add a network service type to a name space, a SERVICE_TYPE_INFO_ABS structure is passed as the ServiceSpecificInfo BLOB member of a SERVICE_INFO structure. Although the ServiceSpecificInfo member generally should not contain pointers, an exception is made in the case of the SERVICE_TYPE_INFO_ABS and SERVICE_TYPE_VALUE_ABS structures.

See Also

SetService, SERVICE_INFO, SERVICE_TYPE_INFO_ABS


Windows Sockets Service Registration and Name Resolution

The service registration and resolution functionality helps you write client server applications. Using this functionality, a service can register its existence with a name space (registration), and a client can find a service within a name space (resolution).


Service Registration and Resolution Definitions

The following functions and structures let you implement service registration and resolution functionality.


Service Registration and Resolution Functions

Use these functions to implement service registration and resolution functionality:

EnumProtocols
GetAddressByName
GetNameByType
GetService
GetTypeByName
SetService


Service Registration and Resolution Structures

Use these structures to implement service registration and resolution functionality:

BLOB
CSADDR_INFO
NS_SERVICE_INFO
PROTOCOL_INFO
SERVICE_ADDRESS
SERVICE_ADDRESSES
SERVICE_INFO
SERVICE_TYPE_INFO_ABS
SERVICE_TYPE_VALUE_ABS