解决[Errno 22] Invalid argument

 

 

 
     
  1. In [1]: import socket 
  2.  
  3. In [2]: host = 'fe80::20c:29ff:fe47:cf8' 
  4.  
  5. In [3]: port = 22 
  6.  
  7. In [4]: res = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) 
  8.  
  9. In [5]: res 
  10. Out[5]: [(1016'', ('fe80::20c:29ff:fe47:cf8'2200))] 
  11.  
  12. In [7]: af, sock_type, proto, canonname, sa = res[0
  13.  
  14. In [8]: sock = socket.socket( af, sock_type, proto) 
  15.  
  16. In [9]: sock.connect( (sa) ) 
  17. --------------------------------------------------------------------------- 
  18. error Traceback (most recent call last) 
  19. /home/liaoxinxi/Dropbox/example_code/pylibssh2/src/9-374898dcad96in () 
  20. ----> 1 sock.connect( (sa) ) 
  21.  
  22. /usr/lib/python2.7/socket.pyc in meth(name, self, *args) 
  23. 222  
  24. 223 def meth(name,self,*args): 
  25. --> 224 return getattr(self._sock,name)(*args) 
  26. 225  
  27. 226 for _m in _socketmethods: 
  28.  
  29. error: [Errno 22] Invalid argument 
  30.  
  31.   

 

 

原因:

刚开始以为是参数类型不对,以为传错参数了,(是非法参数,就是说不接受这种值,本来是0,1中选,你却给了个2,就会说非法)。看了下socket.py,print 下出错位置,args是一个tuple,((‘...’,22,0,0),),后来通过直接构造socketv6代码,

In [97]: s = socket.socket(socket.AF_INET6,socket.SOCK_STREAM)

In [98]: host
Out[98]: 'fe80::20c:29ff:fe47:cf8'

In [100]: s.connect((host,port,0,1))#是一个tuple
---------------------------------------------------------------------------
error Traceback (most recent call last)
/home/liaoxinxi/Dropbox/example_code/pylibssh2/src/ in ()
----> 1 s.connect((host,port,0,1))

/usr/lib/python2.7/socket.pyc in meth(name, self, *args)
222 
223 def meth(name,self,*args):
--> 224 return getattr(self._sock,name)(*args)
225 
226 for _m in _socketmethods:

error: [Errno 101] Network is unreachable

把connect中的1参数改为其他就报了invalid argument,就是说传的参数出错了。为什么官方推荐的getaddrinfo函数出错了呢???

通过getaddrinfo无法得到fe80打头的即本地链路ipv6地址,这样的本地链路地址访问都必须带上网卡号,如ping6 'fe80::20c:29ff:fe47:cf8%eth0,返回的的scope_id一直是0,通过这个scope_id(在RFCs中可看到)放connect的话就会报Invalid argument,要访问本地链路的ipv6,必须指定网卡的序列号,或者通过

child = login('fe80::20c:29ff:fe47:cf8%eth0', 'root', 'nsfocus') 在地址上带上网卡号,这是在nss-mdns上的一个bug引起的。

socket([family[, type[, proto]]]) family是地址族,AF_INET6 AF_INET(default), AF_UNIX, type是sock类型,如SOCK_STREAM(default),SOCK_DGRAM.
解决方法:
1,加上网卡序号,但是有个问题,还未解决通过ifconfig 显示的是eth3,但是能够ping6通的确是eth0,只有一个 网卡
2,注意替换不同的关键字去搜索,引起不同的思考

示例代码:

 

 
     
  1. host 
  2. Out[107]: 'fe80::20c:29ff:fe47:cf8%eth0' 
  3.  
  4. In [108]: res = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) 
  5.  
  6. In [109]: res 
  7. Out[109]: [(1016'', ('fe80::20c:29ff:fe47:cf8%eth0'2202))] 
  8.  
  9.   
  10.  
  11. In [111]: af, sock_type, proto, canonname, sa = res[0
  12.  
  13. In [112]: sock = socket.socket(af,sock_type,proto) 
  14.  
  15. In [113]: sock.connect(sa) 
  16.  
  17. In [114]: