Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Winsock2 listen() blocks?

MSDN says that : Listen() is a blocking call. Code snippet from a function in which i have used listen() is shown below:

sockaddr_in addr    = {0};
int     addrlen = sizeof(addr);
SOCKET  sock_listen;

if(-1 == (sock_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
{
    cout<<"error";
}   

addr.sin_family = AF_INET;
/* Network byte ordered address for loopback */
addr.sin_addr.s_addr= inet_addr("127.0.0.1");
/* Let service provider assign a unique port from dynamic client port range */  
addr.sin_port   = 0;                        

if(-1 == bind(sock_listen, (const sockaddr *)&addr, addrlen))       
{
    CloseHandle((HANDLE)sock_listen_fd);
    cout<<"error";
}

if(-1 == getsockname(sock_listen, (sockaddr *)&addr, &addrlen))
{     
    CloseHandle((HANDLE)sock_listen);
    cout<<"error";
}

u_long mode = 0;
if(SOCKET_ERROR == ioctlsocket(sock_listen, FIONBIO, &mode))
{
    cout<<"ioctl failed";
}

if(SOCKET_ERROR == listen(sock_listen, 1))
{
    cout<<"listen error";
}
cout<<"Passed listen";
if(SOCKET_ERROR == (s = ACL_accept(sock_listen_fd, NULL, NULL)))
{
       cout<<"accept error";
}

By default a socket handle created as blocking type. Inorder to further ensure it called ioctlsocket() to make the socket handle blocking type.

The output is : Passed listen

So, the thread is not blocking at listen(), instead it blocks on accept which according to my knowledge, is the right way. Also in Linux MAN page it is clearly explained :

listen() marks the socket referred to by socket fd as a passive socket, i.e, as a socket that will be used to accept incoming connection requests using accept()

Then why does MSDN says that listen is a blocking Winsock call. Do they just mean any internal waiting for some event?

like image 511
Aravind Avatar asked May 20 '13 08:05

Aravind


3 Answers

All the documentation says is that listen might block, not that it definitely will. It might also be blocking only very briefly, e.g., to wait for the NIC device driver to complete existing activity.

Windows Sockets allows for the installation of third-party providers to support additional protocols or existing protocols with extra features. Since the Winsock SPI does not prohibit third-party providers from blocking on listen, applications should follow the advice provided by MSDN with regards to APCs and nested Winsock calls.

It seems likely that the built-in TCP/IP provider never blocks on listen but AFAIK there is no explicit guarantee of this.

like image 171
Harry Johnston Avatar answered Oct 20 '22 01:10

Harry Johnston


It might be a blocking call in a sense that the OS might need to make sure that the calling thread has exclusive access to the socket, which requires some sort of a lock, which in turn might block the caller if some other thread holds that lock.

Edit 0:

In general, any call into the operating system is an opportunity for a userland thread to be de-scheduled in favor of other higher priority processing. This usually isn't called "blocking" though, but "sleeping" or being "preempted".

like image 27
Nikolai Fetissov Avatar answered Oct 20 '22 01:10

Nikolai Fetissov


If MSDN says that, it is mistaken. It isn't a blocking call. There's nothing to block on, certainly no 'external network event'.

The paragraph that says so is clearly boilerplate copied into too many places.

like image 1
user207421 Avatar answered Oct 20 '22 01:10

user207421