如何强制系统关闭底层套接字
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
当在完成端口的数据被发送出去之后,套接字就会被关闭,这样我们就完成了一个套接字的关闭。
使用 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)
对于非流式套接字,文件描述符在返回响应对象之前被清除。据我所知,在这种情况下无法获得它。
【讨论】:
这很好用。我发现如果我在“响应”回调中使用你的方法,即使是非流式请求,我也可以做到这一点。以上是关于如何强制系统关闭底层套接字的主要内容,如果未能解决你的问题,请参考以下文章