accept 函数 (winsock2.h)
accept 函数允许在套接字上进行传入连接尝试。
语法
SOCKET WSAAPI accept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] int *addrlen
);
参数
[in] s
一个描述符,用于标识已使用 侦 听函数置于侦听状态的套接字。 连接实际上是使用 accept 返回的套接字建立的。
[out] addr
指向接收连接实体地址的缓冲区的可选指针,该地址称为通信层。 addr 参数的确切格式由创建 sockaddr 结构中的套接字时建立的地址系列确定。
[in, out] addrlen
指向包含 addr 参数指向的结构长度的整数的可选指针。
返回值
如果未发生错误, 则 accept 将返回 类型为 SOCKET 的值,该值是新套接字的描述符。 此返回值是建立实际连接的套接字的句柄。
否则,将返回 值 INVALID_SOCKET ,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
addrlen 引用的整数最初包含 addr 指向的空间量。返回时,它将包含返回的地址的实际长度(以字节为单位)。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
指示了传入连接,但随后在接受呼叫之前被远程对等方终止。 | |
addrlen 参数太小或 addr 不是用户地址空间的有效部分。 | |
阻止的 Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。 | |
在接受之前未调用 listen 函数。 | |
阻止 Windows Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。 | |
队列在 输入接受时 为非空,并且没有可用的描述符。 | |
网络子系统失败。 | |
未提供任何缓冲区空间。 | |
:描述符不是套接字。 | |
:引用的套接字不是支持面向连接的服务的类型。 | |
:套接字标记为非阻止,没有要接受的连接。 |
注解
accept 函数提取套接字 上挂起连接队列中的第一个连接。 然后,它会创建并返回新套接字的句柄。 新创建的套接字是将处理实际连接的套接字;它具有 与套接字相同的属性,包括向 WSAAsyncSelect 或 WSAEventSelect 函数注册的异步事件。
如果队列中没有挂起的连接,并且套接字标记为阻塞,则 accept 函数可以阻止调用方,直到存在连接。 如果套接字标记为非阻止,并且队列中没有挂起的连接, 则接受 将返回如下所述的错误。 成功完成 accept 返回新的套接字句柄后,接受的套接字不能用于接受更多连接。 原始套接字保持打开状态,并侦听新的连接请求。
参数 添加器 是一个结果参数,它用连接实体的地址填充,如通信层所称。 addr 参数的确切格式由发生通信的地址系列确定。 addrlen 是 value-result 参数;它最初应包含 addr 指向的空间量;返回时,它将包含返回的地址的实际长度 () 字节。
accept 函数与面向连接的套接字类型(如 SOCK_STREAM)一起使用。 如果 addr 和/或 addrlen 等于 NULL,则不会返回有关接受套接字的远程地址的信息。
示例代码
以下示例演示如何使用 accept 函数。#ifndef UNICODE
#define UNICODE
#endif
#include <winsock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#include <windows.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int wmain(void)
{
//----------------------
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %ld\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket 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.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_port = htons(27015);
inet_pton(AF_INET, "127.0.0.1", &service.sin_addr);
if (bind(ListenSocket,
(SOCKADDR *) & service, sizeof (service)) == SOCKET_ERROR) {
wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//----------------------
// Listen for incoming connection requests.
// on the created socket
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//----------------------
// Create a SOCKET for accepting incoming requests.
SOCKET AcceptSocket;
wprintf(L"Waiting for client to connect...\n");
//----------------------
// Accept the connection.
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else
wprintf(L"Client connected.\n");
// No longer need server socket
closesocket(ListenSocket);
WSACleanup();
return 0;
}
有关使用 accept 函数的另一个示例,请参阅 入门 With Winsock。
ATM 说明
以下是与连接设置相关的重要问题,在将异步传输模式 (ATM) 与 Windows 套接字 2 配合使用时,必须考虑这些问题:
- accept 和 WSAAccept 函数不一定设置远程地址和地址长度参数。 因此,使用 ATM 时,调用方应使用 WSAAccept 函数并将ATM_CALLING_PARTY_NUMBER_IE放在 QoS 结构的 ProviderSpecific 成员中,该成员本身包含在根据 WSAAccept 使用的回调函数的 lpSQOS 参数中。
- 使用 accept 函数时,请注意,在连接建立已遍历发送方和接收方之间的整个距离之前,函数可能会返回 。 这是因为 accept 函数在收到 CONNECT ACK 消息后立即返回 ;在 ATM 中,一旦将 CONNECT 消息处理 (,路径中的下一个开关就会返回 CONNECT ACK 消息,而不是最终) 建立连接的终结点发送 CONNECT ACK。 因此,应用程序应意识到,如果在收到 CONNECT ACK 消息后立即发送数据,则可能会丢失数据,因为可能尚未在发送方和接收方之间建立连接。
Windows 8.1和Windows 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 |