3.1 Socket Functions

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

accept() *

An incoming connection is acknowledged and associated with an immediately created socket. The original socket is returned to the listening state.

bind()

Assign a local name to an unnamed socket.

closesocket() *

Remove a socket from the per-process object reference table. Only blocks if SO_LINGER is set.

connect() *

Initiate a connection on the specified socket.

getpeername()

Retrieve the name of the peer connected to the specified socket.

getsockname()

Retrieve the current name for the specified socket

getsockopt()

Retrieve options associated with the specified socket.

htonl()

Convert a 32-bit quantity from host byte order to network byte order.

htons()

Convert a 16-bit quantity from host byte order to network byte order.

inet_addr()

Converts a character string representing a number in the Internet standard ".'' notation to an Internet address value.

inet_ntoa()

Converts an Internet address value to an ASCII string in ".'' notation i.e. "a.b.c.d''.

ioctlsocket()

Provide control for sockets.

listen()

Listen for incoming connections on a specified socket.

ntohl()

Convert a 32-bit quantity from network byte order to host byte order.

ntohs()

Convert a 16-bit quantity from network byte order to host byte order.

recv() *

Receive data from a connected socket.

recvfrom() *

Receive data from either a connected or unconnected socket.

select() *

Perform synchronous I/O multiplexing.

send() *

Send data to a connected socket.

sendto() *

Send data to either a connected or unconnected socket.

setsockopt()

Store options associated with the specified socket.

shutdown()

Shut down part of a full-duplex connection.

socket()

Create an endpoint for communication and return a socket.


* = The routine can block if acting on a blocking socket.

3.1.1 Blocking/Non blocking & Data Volatility

One major issue in porting applications from a Berkeley sockets environment to a Windows environment involves "blocking"; that is, invoking a function which does not return until the associated operation is completed. The problem arises when the operation may take an arbitrarily long time to complete: an obvious example is a recv() which may block until data has been received from the peer system. The default behavior within the Berkeley sockets model is for a socket to operate in a blocking mode unless the programmer explicitly requests that operations be treated as non-blocking. It is strongly recommended that programmers use the nonblocking (asynchronous) operations if at all possible, as they work significantly better within the nonpreemptive Windows environment. Use blocking operations only if absolutely necessary, and carefully read and understand this section if you must use blocking operations.

Even on a blocking socket, some operations (e.g. bind(), getsockopt(), getpeername()) can be completed immediately. For such operations there is no difference between blocking and non-blocking operation. Other operations (e.g. recv()) may be completed immediately or may take an arbitrary time to complete, depending on various transport conditions. When applied to a blocking socket, these operations are referred to as blocking operations. All routines which can block are listed with an asterisk in the tables 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 section 4.3.13, WSASetBlockingHook(), for a complete description of this mechanism, including pseudocode for the various functions.

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

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

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

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