首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Winsock2如何侦听()块?

Winsock2如何侦听()块?
EN

Stack Overflow用户
提问于 2013-05-20 08:13:03
回答 3查看 823关注 0票数 5

MSDN说: Listen()是一个阻塞调用。下面显示了我在其中使用了listen()函数的代码片段:

代码语言:javascript
复制
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";
}

默认情况下,作为阻塞类型创建的套接字句柄。为了进一步确保它调用ioctlsocket()来使套接字句柄阻塞类型。

输出是:传递侦听

因此,线程并没有阻塞listen(),而是阻塞了accept,据我所知,这是正确的方法。在Linux手册页中也有明确的解释:

侦听()将套接字fd所引用的套接字标记为被动套接字,即为将使用accept()接受传入连接请求的套接字。

那么,为什么MSDN说侦听是阻塞的Winsock调用。他们是说内部在等什么事吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-22 04:12:20

所有的文档都说listen可能会阻塞,而不是说它肯定会阻塞。它也可能只是非常短暂地阻塞,例如,等待NIC设备驱动程序完成现有活动。

Windows套接字允许安装第三方提供程序,以支持附加协议或具有额外功能的现有协议。由于温索克SPI不禁止第三方提供商阻止listen,所以应用程序应该遵循MSDN提供的关于APC和嵌套Winsock调用的建议。

似乎内置的TCP/IP提供程序从来不会阻止listen,但是AFAIK没有明确的保证。

票数 3
EN

Stack Overflow用户

发布于 2013-05-21 12:16:52

在某种意义上,这可能是一个阻塞调用,因为操作系统可能需要确保调用线程具有对套接字的独占访问权,而套接字需要某种类型的锁,如果其他线程持有该锁,则可能会阻塞调用方。

编辑0:

一般来说,对操作系统的任何调用都是用户线程被取消调度的机会,从而有利于其他更高优先级的处理。这通常不是所谓的“阻塞”,而是“睡眠”或“先发制人”。

票数 2
EN

Stack Overflow用户

发布于 2013-05-21 12:16:55

如果MSDN这么说,那就错了。这不是阻拦电话。没有什么可以阻止的,当然也没有“外部网络事件”。

这么说的段落显然是抄袭到太多地方的样板。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16645215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档