This document may be freely redistributed in any form, electronic or otherwise, provided that it is distributed in its entirety and that the copyright and this notice are included. Comments or questions may be submitted via electronic mail to WinSock@MailBag.Intel.Com. Requests to be added to the Windows Sockets mailing list should be addressed to MajorDomo@MailBag.Intel.Com. This specification, archives of the mailing list, and other information on Windows Sockets are available via anonymous FTP from the host SunSite.UNC.Edu, directory /pub/micro/pc-stuff/ms-windows/winsock. Questions about products conforming to this specification should be addressed to the vendors of the products.
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 NetManage, 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.comJ. 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 Frontier 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 NetManage, 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
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.
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.
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.
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 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.
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.
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 to 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.
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.
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.
Value Type Meaning Default Note --------------- --------------- ----------------------- --------------- ---- SO_ACCEPTCON BOOL Socket is listen()ing. FALSE unless a listen() has been performedSO_BROADCAST BOOL Socket is configured FALSE
for the transmission of
broadcast messages.
SO_DEBUG BOOL Debugging is enabled. FALSE (i)
SO_DONTLINGER BOOL If true, the SO_LINGER TRUE
option is disabled..
SO_DONTROUTE BOOL Routing is disabled. FALSE (i)
SO_ERROR int Retrieve error status 0
and clear.
SO_KEEPALIVE BOOL Keepalives are being FALSE
sent.
SO_LINGER struct linger Returns the current l_onoff is 0
FAR * linger options.
SO_OOBINLINE BOOL Out-of-band data is FALSE
being received in the
normal data stream.
SO_RCVBUF int Buffer size for Implementation (i)
receives dependant.
SO_REUSEADDR BOOL The address to which FALSE
this socket is bound
can be used by others.
SO_SNDBUF int Buffer size for sends Implementation (i)
dependant.
SO_TYPE int The type of the socket As created
(e.g. SOCK_STREAM). via socket()
TCP_NODELAY BOOL Disables the Nagle Implementation
algorithm for send dependant.
coalescing.
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.
socket data type and error values
Error codes -- errno, h_errno & WSAGetLastError()
Blocking routines & EINPROGRESS
Maximum number of sockets supported
In UNIX, all handles, including socket handles, are small, non-negative intergers, 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) {...}
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 && WSAGetLastError() == WSAEWOULDBLOCK) {...}
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 socket descriptors.. 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().
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.
TYPICAL BSD STYLE:
r = recv(...); if (r == -1 /* or r < 0 */ && errno == EWOULDBLOCK) {...}PREFERRED STYLE:
r = recv(...); if (r == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) {...}
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 cancelled. 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.
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 descriptor 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 descriptor.
getsockname() Retrieve the current name for the specified socket
getsockopt() Retrieve options associated with the specified socket descriptor.
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 descriptors.
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 descriptor.
shutdown() Shut down part of a full-duplex connection.
socket() Create an endpoint for communication and return a socket descriptor.
* The routine can block if acting on a blocking socket.
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 above and below.
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 will call the blocking hook function 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.
gethostbyaddr()* Retrieve the name(s) and address corresponding to a network address.
gethostname() Retrieve the name of the local host.
gethostbyname()* Retrieve the name(s) and address corresponding to a host name.
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.
Asynchronous select() Mechanism
Accessing a Windows Sockets DLL from an Intermediate DLL
Internal Use of Messages by Windows Sockets Implementations
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 asynchronous message based
WSAAsyncGetServByName() implementation of the standard Berkeley
WSAAsyncGetServByPort() 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
WSAAsyncSelect() allows interest to be declared in the following conditions for a particular socket:
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.
There are (at least) two ways to accomplish this. The simplest method is for the intermediate DLL to have calls similiar 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.
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.
In each routine it is indicated that the header file winsock.h must be included. Header Files 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.
#include <winsock.h>
SOCKET PASCAL FAR accept ( SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen);
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.
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.
#include <winsock.h>
int PASCAL FAR bind ( SOCKET s, const struct sockaddr FAR * name, int namelen);
struct sockaddr { u_short sa_family; char sa_data[14]; };
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. */ } }
#include <winsock.h>
int FAR PASCAL closesocket ( SOCKET s);
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 Socket Options, getsockopt() and setsockopt()) 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" close, because the socket is closed immediately, and any unsent data is lost. Any recv() call on the remote side of the circuit can 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 Socket Options, getsockopt() and setsockopt()), 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.
#include <winsock.h>
int PASCAL FAR connect ( SOCKET s, const struct sockaddr FAR * name, int namelen);
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.
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:
On a blocking socket, the return value indicates success or failure of the connection attempt.
#include <winsock.h>
int PASCAL FAR getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen);
#include <winsock.h>
int PASCAL FAR getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen);
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.
#include <winsock.h>
int PASCAL FAR getsockopt ( SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen);
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 listen()ing. 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 Returns the current linger options. FAR * 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().
#include <winsock.h>
u_long PASCAL FAR htonl ( u_long hostlong);
#include <winsock.h>
u_short PASCAL FAR htons ( u_short hostshort );
#include <winsock.h>
unsigned long PASCAL FAR inet_addr ( const char FAR * cp );
Values specified using the ``.'' notation take one of the following forms:
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.
#include <winsock.h>
char FAR * PASCAL FAR inet_ntoa ( struct in_addr in );
#include <winsock.h>
int PASCAL FAR ioctlsocket ( SOCKET s, long cmd, u_long FAR * argp);
#include <winsock.h>
int PASCAL FAR listen(SOCKET s, int backlog );
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.
#include <winsock.h>
u_long PASCAL FAR ntohl ( u_long netlong);
#include <winsock.h>
u_short PASCAL FAR ntohs ( u_short netshort );
#include <winsock.h>
int PASCAL FAR recv ( int s, char FAR * buf, int len, int flags);
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 size of the buffer supplied. If the datagram is larger than the buffer supplied, 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 abortively disconnected, 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:
#include <winsock.h>
int PASCAL FAR recvfrom ( int s, char FAR * buf, int len, int flags, struct sockaddr FAR * from, int FAR * fromlen );
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 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 abortively disconnected, a recvfrom() 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:
#include <winsock.h>
long PASCAL FAR select ( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout );
The parameter readfds identifies those sockets which are to be checked for readability. If the socket is currently listen()ing, 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 closed abortively, 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 writeability. If a socket is connect()ing (non-blocking), writeability means that the connection establishment is complete. For other sockets, writeability 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 connect()ing (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:
#include <winsock.h>
int PASCAL FAR send ( SOCKET s, const char FAR * buf, int len, int flags );
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:
#include <winsock.h>
int PASCAL FAR sendto ( SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen);
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:
#include <winsock.h>
int PASCAL FAR setsockopt ( SOCKET s, int level, int optname, const char FAR * optval, int optlen);
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 Linger on close if unsent data is present FAR * 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 coalascing.
BSD options not supported for setsockopt() are:
Value Type Meaning --------------- --------------- ----------------------------------------------- SO_ACCEPTCON 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.
#include <winsock.h>
int PASCAL FAR shutdown ( SOCKET s, int how );
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.
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.
#include <winsock.h>
SOCKET PASCAL FAR socket ( int af, int type, int protocol);
The following type specifications are supported:
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 connect()ed to a specific peer, datagrams may be send to that peer send() and may be received from (only) this peer using recv().
#include <winsock.h>
struct hostent FAR * PASCAL FAR gethostbyaddr ( const char FAR * addr, int len, int type );
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:
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.
#include <winsock.h>
struct hostent FAR * PASCAL FAR gethostbyname ( const char FAR * name);
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.
#include <winsock.h>
int PASCAL FAR gethostname ( char FAR * name, int namelen );
#include <winsock.h>
struct protoent FAR * PASCAL FAR getprotobyname ( const char FAR * name);
struct protoent { char FAR * p_name; char FAR * FAR *p_aliases; short p_proto; };The members of this structure are:
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.
#include <winsock.h>
struct protoent FAR * PASCAL FAR getprotobynumber ( int number );
#include <winsock.h>
struct servent FAR * PASCAL FAR getservbyname ( const char FAR * name, const char FAR * proto);
struct servent { char FAR * s_name; char FAR * FAR *s_aliases; short s_port; char FAR * s_proto; };The members of this structure are:
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.
See Also WSAAsyncGetServByName(), getservbyport()
#include <winsock.h>
struct servent FAR * PASCAL FAR getservbyport ( int port, const char FAR * proto);
#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);
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.
If the asynchronous operation could not be initiated, WSAAsyncGetHostByAddr() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#include <winsock.h>
HANDLE PASCAL FAR WSAAsyncGetHostByName ( HWND hWnd, unsigned int wMsg, const char FAR * name, char FAR * buf, int buflen);
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.
If the asynchronous operation could not be initiated, WSAAsyncGetHostByName() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#include <winsock.h>
HANDLE PASCAL FAR WSAAsyncGetProtoByName ( HWND hWnd, unsigned int wMsg, const char FAR * name, char FAR * buf, int buflen);
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.
If the asynchronous operation could not be initiated, WSAAsyncGetProtoByName() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#include <winsock.h>
HANDLE PASCAL FAR WSAAsyncGetProtoByNumber ( HWND hWnd, unsigned int wMsg, int number, char FAR * buf, int buflen);
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.
If the asynchronous operation could not be initiated, WSAAsyncGetProtoByNumber() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#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 );
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.
If the asynchronous operation could not be initiated, WSAAsyncGetHostByAddr() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#include <winsock.h>
HANDLE PASCAL FAR WSAAsyncGetServByPort ( HWND hWnd, unsigned int wMsg, int port, const char FAR * proto, char FAR * buf, int buflen );
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.
If the asynchronous operation could not be initiated, WSAAsyncGetServByPort() returns a zero value, and a specific error number may be retrieved by calling WSAGetLastError().
Windows Sockets suppliers should use the WSAMAKEASYNCREPLY macro when constructing the lParam in the message.
#include <winsock.h>
int PASCAL FAR WSAAsyncSelect ( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent );
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: 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:
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 re-enables notification of that network event.
For FD_READ, FD_OOB, and FD_ACCEPT events, message posting is "level-triggerred." This means that if the reenabling routine is called and the relevent 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:
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 abortively disconnected. 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.
Event: FD_CLOSE
Event: FD_READ
Event: FD_WRITE
Event: FD_OOB
Event: FD_ACCEPT
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().
#include <winsock.h>
int PASCAL FAR WSACancelAsyncRequest ( HANDLE hAsyncTaskHandle );
#include <winsock.h>
int PASCAL FAR WSACancelBlockingCall ( void );
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 comprimised 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.
#include <winsock.h>
int PASCAL FAR WSACleanup ( void );
There must be a call to WSACleanup() for every call to WSAStartup() made by a task. Only the final WSACleanup() 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 WSAENOTINITIALISED.
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.
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.
#include <winsock.h>
int PASCAL FAR WSAGetLastError ( void );
Note that in a Win16 environment WSAGetLastError() is used to retrieve only Windows Sockets API errors. In a Win32 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.
#include <winsock.h>
BOOL PASCAL FAR WSAIsBlocking ( void );
#include <winsock.h>
FARPROC PASCAL FAR WSASetBlockingHook ( FARPROC lpBlockFunc );
When an application invokes a blocking Windows Sockets API operation, the Windows Sockets implementation initiates the operation and then enters a loop which is equivalent 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.
#include <winsock.h>
void PASCAL FAR WSASetLastError ( int iError );
#include <winsock.h>
int PASCAL FAR WSAStartup ( WORD wVersionRequired, LPWSADATA lpWSAData );
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.11.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 App fails
1.0 1.1 1.0 --- --- NotSupp
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 App 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 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 must call WSACleanup() in order to allow the DLL to free any resources allocated by the Windows Sockets DLL 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:
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 does all necessary resource deallocation for the task.
Further issues are discussed in the notes for WSACleanup().
#include <winsock.h>
int PASCAL FAR WSAUnhookBlockingHook ( void );
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.
Windows Sockets code Berkeley equivalent Error Interpretation ----------------------- ----------------------- ------- ---------------- WSAEINTR EINTR 10004 As in standard C WSAEBADF EBADF 10009 As in standard C WSEACCES 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 any Windows 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 Sockets DLL cannot support this app. WSAENOTINITIALISED 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, 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.
Windows Sockets Header File -- winsock.h
#ifndef _WINSOCKAPI_ #include <winsock.h> #endif
The header files provided for compatibility are:
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.
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 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 WSAENOTINITIALISED (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 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_ */
Multithreadedness and blocking routines.
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.
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
Component Description------------------------------- ----------------------------------------------- WINSOCK.DLL The Windows Sockets API implementation DLL
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().
int FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) { int i = set->count; while (i--) if (set->fd_array[i] == fd) return 1; return 0; }
; ; 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
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.
The following people participated in the process as committee members, in working meetings, or in email review. The authors would like to thank everyone who participated in any way, and apologize in advance if we have omitted anyone.
Martin Hall (Moderator) JSB Corporation martinh@jsbus.com Mark Towfiq (Coordinator) Microdyne Corporation towfiq@microdyne.com Geoff Arnold Sun Microsystems, Inc. geoff@east.sun.com Alistair Banks Microsoft alistair@microsoft.com Carl Beame Beame & Whiteside beame@mcmaster,ca David Beaver Microsoft dbeaver@microsoft.com Amatzia BenArtzi NetManage, Inc. amatzia@netmanage.com Mark Beyer Ungermann-Bass mbeyer@ub.com James Van Bokkelen FTP Software jbvb@ftp.com Nelson Bolyard Silicon Graphics, Inc. nelson@sgi.com Pat Bonner Hewlett-Packard p_bonner@cnd.hp.com Isaac Chan Microsoft isaacc@microsoft.com Nestor Fesas Hughes LAN Systems nestor@hls.com Gary Gere Gupta ggere@gupta.com Bill Hayes Hewlett-Packard billh@hpchdpc.cnd.hp.com Hoek Law Citicorp law@dcc.tti.com Paul Hill MIT pbh@athena.mit.edu Graeme Le Roux Moresdawn P/L - Terry Lister Hewlett-Packard tel@cnd.hp.com Lee Murach Network Research lee@nrc.com David Pool Spry, Inc. dave@spry.com Brad Rice Age rice@age.com Allen Rochkind 3Com - Henry Sanders Microsoft henrysa@microsoft.com David Treadwell Microsoft davidtr@microsoft.com Miles Wu Wollongong wu@twg.com Boris Yanovsky NetManage, Inc. boris@netmanage.com J Allard Microsoft Corporation jallard@microsoft.com
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 SunSite.UNC.Edu in /pub/micro/pc-stuff/ms-windows/winsock/winsock-1.1 as winsock.bmp. The suggested color for the logo's title bar is blue, the electrical socket grey, and the text and outline black.
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 translatated 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.]