How to create IPv6 socket at python? Why got the socket.error: (22, 'Invalid argument')?

Jianzhong picture Jianzhong · Sep 27, 2010 · Viewed 9.3k times · Source

I want to ceate Ipv6 socket at python, I do it like this:

#!/usr/bin/env python
import sys
import struct
import socket

host = 'fe80::225:b3ff:fe26:576'
sa = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sa.bind((host , 50000))

But it failed:

socket.error: (22, 'Invalid argument') ?

Can anyone help me? thanks!

I redo it like this, but still cannot work

    >>>host = 'fe80::225:b3ff:fe26:576'
    >>>sa = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    >>>res = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
    >>>family, socktype, proto, canonname, sockaddr = res[0]
    >>>print sockaddr
('fe80::225:b3ff:fe26:576', 50001, 0, 0)
    >>>sa.bind(sockaddr)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<string>", line 1, in bind
socket.error: (22, 'Invalid argument')

Answer

pyfunc picture pyfunc · Sep 27, 2010

There are two parts to the problem

First Issue

You should use the sa.bind(sockaddr) where sockaddr is obtained from getaddrinfo

>>> HOST = 'localhost'
>>> PORT = 50007 
>>> res = socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
>>> family, socktype, proto, canonname, sockaddr = res[1]
>>> proto
17
>>> sockaddr
('fe80::1%lo0', 50007, 0, 1)

Second Issue

If you look at the example provided in the socket documentation at

Socket accepts three arguments

socket( [family[, type[, proto]]])

As per the documentation

Create a new socket using the given address family, 
socket type and protocol number. The address family 
should be AF_INET (the default), AF_INET6 or AF_UNIX. 
The socket type should be SOCK_STREAM (the default), 
SOCK_DGRAM or perhaps one of the other "SOCK_" constants. 
The protocol number is usually zero and may be omitted in that case.

And if you used getaddressinfo to get the values for proto then the value is different from the default 0

But when I executed the following, I get a different protocol value - 17. You may want to investigate this too.

And of course socket.has_ipv6 is True for me.