socket编程:listen()函数详解

本文详细介绍了Windows环境下Winsock API中的listen函数,包括其函数原型、使用示例、参数说明及返回值等内容,并通过示例代码展示了如何初始化Winsock、创建监听套接字并设置地址信息,最终进入监听状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方文档:https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen

1. 函数原型

侦听功能将套接字置于侦听传入连接的状态。

int WSAAPI listen(
  SOCKET s,
  int    backlog
);

2. 使用

#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;
}

3. 参数

SOCKET s:

  • 服务端的socket,也就是socket函数创建的
  • 标识绑定的,未连接的套接字的描述符。

int backlog:

  • 挂起的连接队列的最大长度。
  • 就是说,比如有100个用户链接请求,但是系统一次只能处理20个,那么剩下的80个不能不理人家,所以系统就创建个队列记录这些暂时不能处理,一会儿处理的连接请求,依先后顺序处理,那这个队列到底多大?就是这个参数设置,比如2,那么就允许两个新链接排队。这个不能无限大,那内存就不够了。
  • 我们可以手动设置这个参数,但是别太大了。可能2-10多,~20多。
  • 我们一般填写这个参数为SOMAXCONN
    • 作用是让系统自动选择最合适的个数
    • 不同的系统环境不一样,所以这个合适的数也不一样

4. WSAAPI

  • 调用约定(我们可以忽略,这个是给系统看的,跟我们无关)
  • 决定3个东西
    • 函数名字的编译方式
    • 参数的入栈顺序
    • 函数的调用时间

5. 返回值

  • 成功返回0
  • 失败返回SOCKET_ERROR
    • 具体错误码:WSAGetLastError()
    • 释放:closesocket(socketListen);
    • 清理:WSACleanup();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级D洋葱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值