closesocket 函数 (winsock.h)
closesocket 函数关闭现有套接字。
语法
int closesocket(
[in] SOCKET s
);
参数
[in] s
标识要关闭的套接字的描述符。
返回值
如果未发生错误, 则 closesocket 返回零。 否则,将返回 值 SOCKET_ERROR ,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
网络子系统发生故障。 | |
:描述符不是套接字。 | |
阻止 Windows 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。 | |
(阻止) Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。 | |
套接字标记为非阻止,但 linger 结构的l_onoff成员设置为非零,而 linger 结构的l_linger成员设置为非零超时值。 |
注解
closesocket 函数关闭套接字。 使用它释放在 s 参数中传递的套接字描述符。 请注意,一旦发出 closesocket 函数,系统可能会立即重用传入 s 参数的套接字描述符。 因此,预期对 s 参数中传递的套接字描述符的进一步引用失败并出现错误 WSAENOTSOCK 是不可靠的。 Winsock 客户端不得在另一个 Winsock 函数调用的同时在 上发出 closesocket。
( WSASendTo/ WSARecvWSendTo/ WSARecvFrom/ 的任何挂起的重叠发送和接收操作,以及此进程中任何线程颁发的重叠套接字) 也会被取消。 将执行为这些重叠操作指定的任何事件、完成例程或完成端口操作。 挂起的重叠操作失败,错误状态 WSA_OPERATION_ABORTED。
应用程序不应假定当 closesocket 返回时,套接字上任何未完成的 I/O 操作都保证完成。 closesocket 函数将对未完成的 I/O 操作启动取消,但这并不意味着应用程序将在 closesocket 函数返回时收到这些 I/O 操作的 I/O 完成。 因此,应用程序不应清除 WSAOVERLAPPED 结构 (任何资源,例如) 未完成的 I/O 请求引用,直到 I/O 请求确实完成。
对于每次成功调用套接字,应用程序应始终对 closesocket 进行匹配调用,以便将任何套接字资源返回到系统。
linger 结构维护有关特定套接字的信息,该套接字指定在排队发送数据并在套接字上调用 closesocket 函数时该套接字的行为方式。
linger 结构的l_onoff成员确定套接字在调用 closesocket 函数后是否应在指定的时间内保持打开状态,以允许发送排队数据。 可以通过两种方式修改此成员:
- 调用 setockopt 函数,并将 optname 参数设置为 SO_DONTLINGER。 optval 参数确定如何修改 l_onoff 成员。
- 调用 setockopt 函数,并将 optname 参数设置为 SO_LINGER。 optval 参数指定如何修改l_onoff和l_linger成员。
linger 结构的 l_linger 成员确定套接字应保持打开状态的时间量(以秒为单位)。 仅当 linger 结构的l_onoff成员为非零时,此成员才适用。
套接字的默认参数是 linger 结构的l_onoff成员为零,表示套接字不应保持打开状态。 linger 结构的l_linger成员的默认值为零,但当l_onoff成员设置为零时,此值将被忽略。
若要使套接字保持打开状态,应用程序应将 l_onoff 成员设置为非零值,并将 l_linger 成员设置为所需的超时(以秒为单位)。 若要禁用套接字保持打开状态,应用程序只需将 linger 结构的 l_onoff 成员设置为零。
如果应用程序调用 optname 参数设置为 SO_DONTLINGER的 setsockopt 函数,将 l_onoff 成员设置为非零值,则不指定 l_linger 成员的值。 在这种情况下,使用的超时依赖于实现。 如果以前通过调用 setockopt 函数( optname 参数设置为 SO_LINGER) )为套接字 ( 建立了以前的超时,则服务提供程序应恢复此超时值。
closesocket 函数的语义受设置 linger 结构成员的套接字选项的影响。
l_onoff | l_linger | 关闭类型 | 等待关闭? |
---|---|---|---|
零 | 不在乎 | 优雅关闭 | 否 |
零 | 零 | 硬色调 | 否 |
零 | 零 |
如果所有数据在 l_linger 成员中指定的超时值内发送,则为正常。
如果无法在 l_linger 成员中指定的超时值内发送所有数据,则很难。 |
是 |
如果 LINGER 结构的l_onoff成员在流套接字上为零,则 closesocket 调用将立即返回,并且无论套接字是阻塞还是非阻塞,都不会收到 WSAEWOULDBLOCK。 但是,如果可能,在关闭基础套接字之前,将发送任何排队等待传输的数据。 这也称为正常断开连接或关闭。 在这种情况下,Windows 套接字提供程序无法在任意时间段内释放套接字和其他资源,从而影响希望使用所有可用套接字的应用程序。 这是套接字的默认行为。
如果 linger 结构的l_onoff成员为非零且l_linger成员为零,则即使尚未发送或确认排队数据,也不会阻止 closesocket。 这称为硬关闭或中止关闭,因为套接字的虚拟线路会立即重置,并且任何未发送的数据都将丢失。 在 Windows 上,线路远程端的任何 recv 调用都将失败并出现 WSAECONNRESET。
如果 linger 结构的l_onoff成员设置为非零,并且l_linger成员在阻止套接字上设置为非零超时,则 closesocket 调用将一直阻止,直到发送剩余数据或超时过期为止。 如果在 l_linger 成员中指定的超时值内发送所有数据,则这称为正常断开连接或关闭。 如果超时在发送所有数据之前过期,Windows 套接字实现会在 closesocket 返回之前终止连接,这称为硬关闭或中止关闭。
不建议将 linger 结构的 l_onoff 成员设置为非零,并将非阻止套接字上具有非零超时间隔的 l_linger 成员。 在这种情况下,如果关闭操作无法立即完成,对 closesocket 的 调用将失败并显示 WSAEWOULDBLOCK 错误。 如果 closesocket 失败并出现 WSAEWOULDBLOCK ,则套接字句柄仍然有效,并且不会启动断开连接。 应用程序必须再次调用 closesocket 才能关闭套接字。
如果 linger 结构的l_onoff成员为非零值,并且 l_linger 成员是阻塞套接字上的非零超时间隔,则 closesocket 函数的结果不能用于确定是否所有数据都已发送到对等方。 如果在 l_linger 成员中指定的超时过期之前发送数据,或者如果连接中止, 则 closesocket 函数不会返回错误代码, (closesocket 函数的返回值为零) 。
closesocket 调用只会阻止,直到所有数据都已传递到对等方或超时过期。 如果连接因超时过期而重置,则套接字不会进入TIME_WAIT状态。 如果所有数据在超时期限内发送,则套接字可以进入TIME_WAIT状态。
如果 linger 结构的l_onoff成员为非零,并且 l_linger 成员在阻塞套接字上为零超时间隔,则对 closesocket 的调用将重置连接。 套接字不会进入TIME_WAIT状态。
可以在将 optname 参数设置为 SO_LINGER 的情况下调用 getsockopt 函数,以检索与套接字关联的 linger 结构的当前值。
下面是 closesocket 行为的摘要:
- 如果 LINGER 结构的l_onoff成员为零, (套接字) 的默认值,则 closesocket 将立即返回,连接在后台正常关闭。
- 如果 linger 结构的l_onoff成员设置为非零,并且 l_linger 成员设置为零 (则没有超时) closesocket 会立即返回并且连接重置或终止。
- 如果 linger 结构的 l_onoff 成员设置为非零值,并将l_linger成员设置为非零超时:– 对于阻塞套接字,则 closesocket 会阻止,直到发送所有数据或超时到期为止。
– 对于非阻止套接字, closesocket 会立即返回指示失败。
有关详细信息 ,请参阅正常关闭、挥之不去的选项和套接字关闭 。
IrDA 套接字说明
请记住以下几点:
- 必须显式包含 Af_irda.h 头文件。
- 支持标准挥之不去的选项。
- 尽管 IrDA 不提供正常关闭,但 IrDA 将推迟关闭,直到清除接收队列。 因此,应用程序可以发送数据并立即调用 套接字 函数,并确信接收方会在接收FD_CLOSE消息之前复制数据。
ATM 说明
以下是使用异步传输模式 (ATM) 和 Windows 套接字 2 时与连接断开相关的重要问题:
- 将 closesocket 或 关闭 函数与SD_SEND或SD_BOTH会导致在控制通道上发出 RELEASE 信号。 由于 ATM 使用单独的信号和数据通道,RELEASE 信号可能会在最后一个数据到达其目标之前到达远程端,从而导致数据丢失。 一种可能的解决方案是在发送的最后一个数据与 ATM 套接字的 closesocket 或 shutdown 函数调用之间设置足够的延迟。
- ATM 不支持半关闭。
- 中止和正常断开连接都会导致发布信号以相同的原因字段发出。 在任一情况下,在套接字的远程端接收的数据仍会传递到应用程序。 有关详细信息 ,请参阅正常关闭、挥之不去的选项和套接字关闭 。
Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。
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 |
标头 | winsock.h (包括 Winsock2.h) |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |