How to create a socket.socket() object from a socket fd?

Christian Heimes christian at python.org
Sat Jan 21 18:28:48 EST 2017


On 2017-01-21 23:41, Grant Edwards wrote:
> On 2017-01-21, Grant Edwards <grant.b.edwards at gmail.com> wrote:
> 
>> Given a Unix file discriptor for an open TCP socket, I can't figure
>> out how to create a python 2.7 socket object like those returned by
>> socket.socket()
>>
>> Based on the docs, one might think that socket.fromfd() would do that
>> (since the docs say that's what it does):
> [...]
>> That prompts a question: given a "socket object" as returned by
>> socket.fromfd(), how does one create a "socket._socketobject object"
>> as returned by socket.socket()?
> 
> Of course I figured it out immediately after spending 15 minutes
> whinging about it.
> 
> help(socket.socket) gives you a hint:
> 
> class _socketobject(__builtin__.object)
>  |  socket([family[, type[, proto]]]) -> socket object
>  |  
> [...] 
>  |  
>  |  Methods defined here:
>  |  
>  |  __init__(self, family=2, type=1, proto=0, _sock=None)
>  |  
> 
> Ah! There's a keyword argument that doesn't appear in the docs, so
> let's try that...
> 
>   context = ssl.create_default_context()
>   [...]  
>   sock = socket.fromfd(fd2,socket.AF_INET,socket.SOCK_STREAM)
>   nsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM,_sock=sock)
>   conn = context.wrap_socket(nsock, server_hostname="whatever.invalid")
> 
> That works.

You might be interested in my small module
https://pypi.python.org/pypi/socketfromfd/ . I just releases a new
version with a fix for Python 2. Thanks for the hint! :)

The module correctly detects address family, socket type and proto from
a fd. It works correctly with e.g. IPv6 or Unix sockets. Ticket
https://bugs.python.org/issue28134 has additional background information
on the matter.

Christian



More information about the Python-list mailing list