Hi
Problem:
========
It seems that something blocks all the sockets. How can I find out if
something like that is happening and how can I change it ?
Maybe this will provide you with some information you are looking for.
Resolution:
==========
Reference Link:
http://support.microsoft.com/default.aspx?scid=kb;[LN];181611
INFO: Socket Overlapped I/O Versus Blocking/Non-blocking Mode
SUMMARY
========
This article explains the difference between a socket's overlapped I/O
attribute and the socket's blocking or non-blocking mode.
MORE INFORMATION
=================
When a socket is created, by default it is a blocking socket. You can use
the FIONBIO command in the ioctlsocket API call, WSAEventSelect, or
WSAAysncSelect to change the socket mode from blocking to non-blocking. If
a Winsock call cannot complete immediately, the call fails and
WSAGetLastError returns a WSAEWOULDBLOCK error if it's a non-blocking
socket, or the call blocks until the operation completes if it's a blocking
socket.
The socket overlapped I/O attribute is different from the socket's blocking
or non-blocking mode. Although the current Winsock implementation requires
overlapped I/O attribute for non-blocking socket mode, they are
conceptually independent and their programming model is different too. To
create a socket with the overlapped I/O attribute, you can either use the
socket API or the WSASocket API with the WSA_FLAG_OVERLAPPED flag set. If
an overlapped I/O operation can not complete immediately, the call fails
and WSAGetLastError or GetLastError return WSA_IO_PENDING or
ERROR_IO_PENDING, which is actually the same define as WSA_IO_PENDING. For
additional information, please see the following article in the Microsoft
Knowledge Base:
179942 INFO: WSA_FLAG_OVERLAPPED Is Needed For Non-Blocking Sockets
Please note that once a socket is created, there is no way to change the
socket overlapped attribute. However, you can call the setsockopt API with
SO_OPENTYPE option on any socket handles including an INVALID_SOCKET to
change the overlapped attributes for all successive socket calls in the
same thread. The default SO_OPENTYPE option value is 0, which sets the
overlapped attribute. All non-zero option values make the socket
synchronous and make it so that you cannot use a completion function.
By setting a socket's overlapped I/O attribute it doesn't mean that the
socket will perform an overlapped I/O operation. For example, if you
specify NULL for both the completion function and the overlapped structure
in WSARecv and WSASend, or you simply call recv or send functions, they
will complete in a blocking fashion. To make sure the I/O is performed in
an overlapped fashion you need to provide an overlapped structure in your
I/O function, depending on the function you use.
Overlapped I/O
In Winsock 1, you create an overlapped socket using the socket API, and use
Win32 file I/O API ReadFile, ReadFileEx, WriteFile, WriteFileEx to perform
overlapped I/O on the socket handle. In Winsock 2, you create an overlapped
socket using WSASocket with the WSA_FLAG_OVERLAPPED flag, or simply using
the socket API. You can use the above Win32 file I/O APIs or Winsock 2
WSASend, WSASendTo, WSARecv, and WSARecvFrom to initiate an overlapped I/O
operation.
If you use the SO_RCVBUF and SO_SNDBUF option to set zero TCP stack receive
and send buffer, you basically instruct the TCP stack to directly perform
I/O using the buffer provided in your I/O call. Therefore, in addition to
the non- blocking advantage of the overlapped socket I/O, the other
advantage is better performance because you save a buffer copy between the
TCP stack buffer and the user buffer for each I/O call. But you have to
make sure you don't access the user buffer once it's submitted for
overlapped operation and before the overlapped operation completes.
To determine whether the overlapped I/O operation is completed, you can use
one of the following options:
o You can provide an event handle in an overlapped structure used in the
I/O call and wait on the event handle to signal.
o Use GetOverlappedResult or WSAGetOverlappedResult to poll the status of
the overlapped I/O operation. On Windows NT, you can specify NULL as the
event handle in the overlapped structure. However, on Windows 95 the
overlapped structure needs to contain a manual reset event handle.
WSAGetOverlappedResult on Windows 98 and Windows Millennium Edition (ME) is
modified such that it will behave like Windows NT and can also poll the
completion status with a NULL event handle in the overlapped structure.
o Use ReadFileEx, WriteFileEx, WSARecv, WSARecvFrom, WSASend, or WSASendTo
and choose to provide a completion function to be called when the
overlapped I/O operation has completed. If you use the completion function
approach, at some point after you have issued the overlapped I/O operation
you need to issue a Win32 wait function or a WSA version of wait function
to wait on a non-signaled handle to put your current thread into an
alertable wait state. When the overlapped I/O operation completes, your
completion function is called, your wait function is going to return
WAIT_IO_COMPLETION, and your alertable wait thread wakes up.
o Use GetQueuedCompletionStatus and associate a socket, along with the
overlapped I/O attribute set, with a Windows NT I/O Completion Port(IOCP).
With IOCP, you don't need to supply a completion function, wait on an event
handle to signal, or poll the status of the overlapped operation. Once you
create the IOCP and add your overlapped socket handle to the IOCP, you can
start the overlapped operation by using any of the I/O APIs mentioned above
(except recv, recvfrom, send, or sendto). You will have your worker thread
block on GetQueuedCompletionStatus API waiting for an I/O completion
packet. When an overlapped I/O completes, an I/O completion packet arrives
at the IOCP and GetQueuedCompletionStatus returns.
IOCP is the Windows NT Operating System support for writing a scalable,
high throughput server using very simple threading and blocking code on
overlapped I/O operations. Thus there can be a significant performance
advantage of using overlapped socket I/O with Windows NT IOCPs.
Blocking and Non-Blocking Mode
When a socket is created, by default it is a blocking socket. Under
blocking mode socket I/O operations, connect and accept operations all
block until the operation in question is completed. To change the socket
operation mode from blocking mode to non-blocking mode, you can either use
WSAAsyncSelect, WSAEventSelect, or the FIONBIO command in the ioctlsocket
API call.
WSAAsyncSelect maps socket notifications to Windows messages and is the
best model for a single threaded GUI application.
WSAEventSelect uses WSAEnumNetworkEvents to determine the nature of the
socket notification on the signaling event and maps socket notifications by
signaling an event. This is a useful model for non-GUI applications that
lack a message pump, such as a Windows NT service application.
The FIONBIO command in the ioctlsocket API call puts the socket into non-
blocking mode as well. But you need to poll the status of the socket by
using the select API.
Update: Setting SO_RCVBUF to zero with overlapped recv is not necessary for
Windows 2000, which can directly copy the data to application's recv
buffer. Setting SO_SNDBUF to zero with overlapped send on Windows 2000
still has the same benefit of saving one memory copy as on Windows NT 4.0.
It is also important that the application issues several outstanding
overlapped send's or recv's if the application sets the corresponding stack
buffer to 0.
Shilpa Sinha
This posting is provided "AS IS" with no warranties, and confers no rights.