listen 函数 (winsock2.h)

侦听函数将套接字置于侦听传入连接的状态。

语法

int WSAAPI listen(
  [in] SOCKET s,
  [in] int    backlog
);

参数

[in] s

标识绑定的未连接的套接字的描述符。

[in] backlog

挂起的连接队列的最大长度。 如果设置为 SOMAXCONN,则负责套接字 的基础 服务提供商会将积压工作设置为最大合理值。 如果设置为 SOMAXCONN_HINT (N) (其中 N 为数字) ,则积压工作值为 N,调整为在 200、65535) (范围内。 请注意, SOMAXCONN_HINT 可用于将积压工作设置为比 SOMAXCONN 更大的值。

SOMAXCONN_HINT 仅受 Microsoft TCP/IP 服务提供商支持。 没有用于获取实际积压工作值的标准预配。

返回值

如果未发生错误, 则侦听 返回零。 否则,将返回 值 SOCKET_ERROR ,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

错误代码 含义
WSANOTINITIALIZED
在使用此函数之前,必须成功调用 WSAStartup
WSAENETDOWN
网络子系统发生故障。
WSAEADDRINUSE
套接字的本地地址已在使用中,并且未标记为允许使用 SO_REUSEADDR 重用地址。 此错误通常在 绑定 函数执行期间发生,但如果 绑定到 涉及ADDR_ANY) 的部分通配符地址 (,并且需要在此函数时提交特定地址,则可能会延迟到此函数。
WSAEINPROGRESS
阻止 Windows 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。
WSAEINVAL
套接字尚未绑定。
WSAEISCONN
:套接字已连接。
WSAEMFILE
无法提供更多套接字描述符。
WSAENOBUFS
未提供任何缓冲区空间。
WSAENOTSOCK
:描述符不是套接字。
WSAEOPNOTSUPP
引用的套接字不是支持 侦听 操作的类型。

注解

若要接受连接,首先使用套接字函数创建 套接字 ,并使用 绑定 函数绑定到本地地址。 使用 listen 指定传入连接的积压工作,然后使用 accept 函数接受连接。 面向连接的套接字(例如 SOCK_STREAM 类型的套接字)用于 侦听套接字将置于被动模式,其中传入的连接请求被进程确认并排队等待接受。

SOMAXCONN积压工作的值是一个特殊常量,指示负责套接字 的基础服务提供商将挂起连接队列的长度设置为最大合理值。

在 Windows 套接字 2 上,此最大值默认为一个大值, (通常为数百个或更多) 。

在蓝牙应用程序中调用 侦听 函数时,强烈建议对 积压工作 参数使用低得多的值, (通常为 2 到 4) ,因为只接受少数客户端连接。 这会减少分配供侦听套接字使用的系统资源。 这一相同建议适用于其他只需要几个客户端连接的网络应用程序。

侦听函数通常由一次可以有多个连接请求的服务器使用。 如果连接请求到达且队列已满,客户端将收到指示 WSAECONNREFUSED 的错误。

如果没有可用的套接字描述符, 则侦听 会尝试继续正常运行。 如果描述符可用,则稍后对 listenaccept 的调用会将队列重新填充为 积压工作 参数指定的当前或最新值(如果可能),并恢复侦听传入连接。

如果在已侦听套接字上调用 listen 函数,它将返回成功,而不会更改 积压工作 参数的值。 在侦套接字的后续调用中,将积压工作参数设置为 0 不被视为正确重置,尤其是在套接字上存在连接时。

注意 发出阻止的 Winsock 调用(例如 侦听)时,Winsock 可能需要等待网络事件,然后才能完成调用。 在这种情况下,Winsock 执行可发出警报的等待, (在同一线程上计划的 APC) 异步过程调用可能会中断。 在 APC 内发出另一个阻止 Winsock 调用,该调用中断了同一线程上正在进行的阻止 Winsock 调用将导致未定义的行为,并且 Winsock 客户端绝不能尝试。
 

示例代码

以下示例演示如何使用 listen 函数。
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

int wmain()
{

    //----------------------
    // Initialize Winsock
    WSADATA wsaData;
    int iResult = 0;

    SOCKET ListenSocket = INVALID_SOCKET;
    sockaddr_in service;

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup() failed with error: %d\n", iResult);
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for incoming connection requests.
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);

    iResult = bind(ListenSocket, (SOCKADDR *) & service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind function failed with error %d\n", WSAGetLastError());
        iResult = closesocket(ListenSocket);
        if (iResult == SOCKET_ERROR)
            wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // Listen for incoming connection requests 
    // on the created socket
    if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR)
        wprintf(L"listen function failed with error: %d\n", WSAGetLastError());

    wprintf(L"Listening on socket...\n");

    iResult = closesocket(ListenSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    WSACleanup();
    return 0;
}

示例代码

有关使用 listen 函数的另一个示例,请参阅 入门 With Winsock

IrDA 套接字说明

  • 必须显式包含 Af_irda.h 头文件。

兼容性

积压工作参数限制 (无提示) 基础服务提供商确定的合理值。 非法值将替换为最接近的法定值。 没有标准预配来找出实际的积压工作值。

Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。

要求

要求
最低受支持的客户端 Windows 8.1,Windows Vista [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 winsock2.h
Library Ws2_32.lib
DLL Ws2_32.dll

另请参阅

Winsock 函数

Winsock 参考

accept

connect

socket