SO_CONDITIONAL_ACCEPT套接字选项旨在允许应用程序决定是否接受侦听套接字上的传入连接。
套接字选项值
表示此套接字选项的常量0x3002。
Syntax
int setsockopt(
(SOCKET) s, // descriptor identifying a socket
(int) SOL_SOCKET, // level
(int) SO_CONDITIONAL_ACCEPT, // optname
(char *) optval, // input buffer,
(int) optlen, // size of input buffer
);
参数
-
s [in]
-
标识套接字的描述符。
-
级别 [in]
-
定义选项的级别。 对此作使用 SOL_SOCKET 。
-
optname [in]
-
要为其设置值的套接字选项。 对此作使用 SO_CONDITIONAL_ACCEPT 。
-
optval [out]
-
指向缓冲区的指针,其中包含要设置的选项的值。 此参数应指向等于或大于 DWORD 值大小的缓冲区。
此值被视为布尔值,0 用于指示 FALSE (已禁用)和非零值以指示 TRUE (已启用)。
-
optlen [in, out]
-
指向 optval 缓冲区的大小(以字节为单位)的指针。 此大小必须等于或大于 DWORD 值的大小。
返回值
如果作成功完成, 则 setsockopt 返回零。
如果作失败,将返回SOCKET_ERROR值,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
| 错误代码 | Meaning |
|---|---|
| 在使用此函数之前,必须进行成功的 WSAStartup 调用。 |
|
| 网络子系统已失败。 |
|
|
optval 或 optlen 参数之一指向不在用户地址空间的有效部分的内存。 如果 optlen 参数指向的值小于 DWORD 值的大小,也会返回此错误。 |
|
| 正在阻止 Windows 套接字 1.1 调用,或者服务提供商仍在处理回调函数。 |
|
|
级别参数未知或无效。 如果套接字已处于侦听状态,也会返回此错误。 |
|
| 该选项未知或不受指定的协议系列支持。 |
|
| 描述符不是套接字。 |
注解
使用 SO_CONDITIONAL_ACCEPT 套接字选项调用的 setsockopt 函数允许应用程序决定是否接受侦听套接字上的传入连接。 默认情况下禁用套接字的条件接受选项(设置为 FALSE)。
启用此套接字选项后,TCP 堆栈不会自动接受连接。 它等待应用程序指示它通过向 WSAAccept 函数注册的条件接受回调接受连接。 收到连接请求后,Winsock 将调用应用程序注册的条件接受回调。 仅当条件接受回调返回 CF_ACCEPT 时,Winsock 才会通知传输完全接受连接。
当 SO_CONDITIONAL_ACCEPT 套接字选项设置为启用(设置为 TRUE)时,这会对套接字产生若干副作用:
- 这会禁用 TCP 堆栈的内置 SYN 攻击防护防御,因为应用程序现在正在获取接受连接的所有权。
- 这实际上会禁用侦听积压工作,因为无法代表侦听套接字接受连接。 在应用程序完全接受使用 CF_ACCEPT 机制之前,永远不会完全接受连接。
- 这也意味着应用程序应始终处于状态,以便随时处理接受回调以接受连接。 如果应用程序正忙于执行其他处理,则客户端可能会在应用程序实际接受连接之前超时。 这会导致客户端体验不佳。
- 某些 TCP 堆栈优化不适用于完全接受的连接,即使在条件接受完成后也是如此。 这可以减少整个生命周期内连接的性能。
通常,应用程序使用条件接受的主要原因是检查连接客户端使用的源 IP 地址或端口,然后决定接受或拒绝连接。 但是,如果未启用SO_CONDITIONAL_ACCEPT选项,应用程序允许 TCP 堆栈和侦听积压工作按预期方式工作,则应用程序可能会更好地执行。 然后,当应用程序处理接受的连接时,如果连接来自 IP 源地址或端口不正确,则应用程序只能关闭套接字。 此行为的安全缺点是,现在客户端已确认应用程序正在侦听 IP 地址和端口,因为它强制关闭了以前接受的连接。 但是,启用 SO_CONDITIONAL_ACCEPT 的缺点通常超过此限制。
使用 SO_CONDITIONAL_ACCEPT 套接字选项调用的 getsockopt 函数允许应用程序检索条件接受选项的当前状态,尽管此功能通常未使用。 如果应用程序需要在套接字上启用条件接受,它只会调用 setsockopt 函数来启用该选项。
请注意, Ws2def.h 头文件自动包含在 Winsock2.h 中,不应直接使用。
要求
| Requirement | 价值 |
|---|---|
| 支持的最低客户端 |
Windows Vista [仅限桌面应用] |
| 支持的最低服务器 |
Windows Server 2008 [仅限桌面应用] |
| Header |
|
另请参阅