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();
- 具体错误码: