如何强制系统关闭底层套接字

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何强制系统关闭底层套接字相关的知识,希望对你有一定的参考价值。

Windows SDK 编程,调用 closesocket 有可能会返回失败,关闭不成功,而我也不能无限期等待成功调用 closesocket 才结束线程,因此需要一种方法强制系统关闭当前套接字。说明一下,我的进程不能结束,所以不能依靠结束进程来释放所有资源。我的项目也不适合搞心跳包机制。所以必须能强制关闭套接字,让对端在收发数据不成功时能判断出我这边已经断开。

我们在利用IOCP(完成端口)进行程序设计的时候,经常要关闭一些不满足条件的套接字。假如我们直接采用closesocket方法进行关闭的话,绑定到IO端口的此套接字的未发送的数据就会丢失,这种情况是我们不愿意发生的。下面介绍一种合理关闭此套接字的方法:
首先,利用setsockopt(MSDN)函数设定套接字的选项,我们把此套接字设定为:假如有数据未发送,当数据发送完后再关闭此套接字。

步骤/方法

    1

    代码如下:
    LINGER lingerStruct;
    lingerStruct.l_onoff = 1;
    lingerStruct.l_linger = 0;
    setsockopt(Socket, SOL_SOCKET, SO_LINGER,
    (char *)&lingerStruct, sizeof(lingerStruct) );
    //

    2

    // Now close the socket handle. This will do an abortive or graceful close, as requested.
    CancelIo((HANDLE) Socket);
    closesocket(Socket);
    clientSocket = INVALID_SOCKET;

    3

    当在完成端口的数据被发送出去之后,套接字就会被关闭,这样我们就完成了一个套接字的关闭。

参考技术A

使用 Python 请求时如何获取底层套接字

【中文标题】使用 Python 请求时如何获取底层套接字【英文标题】:How to get the underlying socket when using Python requests 【发布时间】:2015-11-25 11:17:38 【问题描述】:

我有一个 Python 脚本,它使用 requests 库创建许多短期的同时连接。我特别需要找出每个连接使用的源端口,我认为我需要为此访问底层套接字。有没有办法通过响应对象得到这个?

【问题讨论】:

另一种方法是在 Windows 中 netstat -a 可以列出所有进程以及所使用的端口。您可以编写一个 python 脚本来获取此命令的输出,然后进行进一步的工作。没那么难。不确定requests lib 是否可以做到这一点。 我的程序中有很多短暂的同时连接。没有办法知道哪个端口属于哪个连接。 您可以检索应用程序使用的所有端口,但不能使用任何内置命令 (Windows) 来查找应用程序的哪个连接正在使用哪个端口号。我建议在 Superuser.com 中询问 【参考方案1】:

对于流连接(使用stream=True 参数打开的连接),您可以在响应对象上调用.raw.fileno() 方法来获取打开的文件描述符。

您可以使用socket.fromfd(...) 方法从描述符创建 Python 套接字对象:

>>> import requests
>>> import socket
>>> r = requests.get('http://google.com/', stream=True)
>>> s = socket.fromfd(r.raw.fileno(), socket.AF_INET, socket.SOCK_STREAM)
>>> s.getpeername()
('74.125.226.49', 80)
>>> s.getsockname()
('192.168.1.60', 41323)

对于非流式套接字,文件描述符在返回响应对象之前被清除。据我所知,在这种情况下无法获得它。

【讨论】:

这很好用。我发现如果我在“响应”回调中使用你的方法,即使是非流式请求,我也可以做到这一点。

以上是关于如何强制系统关闭底层套接字的主要内容,如果未能解决你的问题,请参考以下文章

WSA UDP 套接字无法重用,因为它强制关闭连接

应用程序强制在启动时关闭

套接字通信底层原理

使用 Python 请求时如何获取底层套接字

如何删除 CLOSE_WAIT 套接字连接

操作系统如何在接受同一个套接字的多个进程之间进行负载平衡?