closesocket 函数 (winsock.h)

closesocket 函数关闭现有套接字。

语法

int closesocket(
  [in] SOCKET s
);

参数

[in] s

标识要关闭的套接字的描述符。

返回值

如果未发生错误, 则 closesocket 返回零。 否则,将返回 值 SOCKET_ERROR ,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

错误代码 含义
WSANOTINITIALIZED
在使用此函数之前,必须成功调用 WSAStartup
WSAENETDOWN
网络子系统发生故障。
WSAENOTSOCK
:描述符不是套接字。
WSAEINPROGRESS
阻止 Windows 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。
WSAEINTR
(阻止) Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。
WSAEWOULDBLOCK
套接字标记为非阻止,但 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_DONTLINGERoptval 参数确定如何修改 l_onoff 成员。
  • 调用 setockopt 函数,并将 optname 参数设置为 SO_LINGERoptval 参数指定如何修改l_onoffl_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 之前调用关闭, (请参阅正常关闭、徘徊选项和套接字关闭以获取详细信息) 。 另请注意,调用 closesocket 后不会发布FD_CLOSE网络事件。
 

下面是 closesocket 行为的摘要:

  • 如果 LINGER 结构的l_onoff成员为零, (套接字) 的默认值,则 closesocket 将立即返回,连接在后台正常关闭。
  • 如果 linger 结构的l_onoff成员设置为非零,并且 l_linger 成员设置为零 (则没有超时) closesocket 会立即返回并且连接重置或终止。
  • 如果 linger 结构的 l_onoff 成员设置为非零值,并将l_linger成员设置为非零超时:– 对于阻塞套接字,则 closesocket 会阻止,直到发送所有数据或超时到期为止。

    – 对于非阻止套接字, closesocket 会立即返回指示失败。

有关详细信息 ,请参阅正常关闭、挥之不去的选项和套接字关闭

注意 发出阻止 Winsock 调用(如 closesocket)时,Winsock 可能需要等待网络事件,才能完成调用。 在这种情况下,Winsock 执行可发出警报的等待, (在同一线程上计划的 APC) 异步过程调用可能会中断该等待。 在 APC 内发出另一个阻止 Winsock 调用,该调用中断了同一线程上正在进行的阻止 Winsock 调用将导致未定义的行为,并且 Winsock 客户端绝不能尝试。
 

IrDA 套接字说明

请记住以下几点:

  • 必须显式包含 Af_irda.h 头文件。
  • 支持标准挥之不去的选项。
  • 尽管 IrDA 不提供正常关闭,但 IrDA 将推迟关闭,直到清除接收队列。 因此,应用程序可以发送数据并立即调用 套接字 函数,并确信接收方会在接收FD_CLOSE消息之前复制数据。

ATM 说明

以下是使用异步传输模式 (ATM) 和 Windows 套接字 2 时与连接断开相关的重要问题:

  • closesocket关闭 函数与SD_SEND或SD_BOTH会导致在控制通道上发出 RELEASE 信号。 由于 ATM 使用单独的信号和数据通道,RELEASE 信号可能会在最后一个数据到达其目标之前到达远程端,从而导致数据丢失。 一种可能的解决方案是在发送的最后一个数据与 ATM 套接字的 closesocketshutdown 函数调用之间设置足够的延迟。
  • ATM 不支持半关闭。
  • 中止和正常断开连接都会导致发布信号以相同的原因字段发出。 在任一情况下,在套接字的远程端接收的数据仍会传递到应用程序。 有关详细信息 ,请参阅正常关闭、挥之不去的选项和套接字关闭

Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。

Windows 8.1Windows 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

另请参阅

正常关闭、挥之不去的选项和套接字关闭

WSAAsyncSelect

WSADuplicateSocket

WSAOVERLAPPED

Winsock 函数

Winsock 参考

accept

getsockopt

ioctlsocket

萦绕

setsockopt

socket