Python笔记:socket模块的getaddrinfo详解

函数原型:socket.getaddrinfo(hostport[family[socktype[proto[flags]]]])

返回值:[(family, socktype, proto, canonname, sockaddr)]有元组组成的列表,元组里面包含5个元素,其中sockaddr是(host,port)

  • family: 表示socket使用的协议簇。常用的协议簇包括AF_UNIX(本机通信)/AF_INET(TCP/IP协议簇中的IPv4协议)/AF_INET6(TCP/IP协议簇中的IPv4协议)。在python的socket包中,用1表示AF_UNIX,2表示AF_INET,10表示AF_INET6。
  • sockettype:表示socket的类型。常见的socket类型包括SOCK_STREAM(TCP流)/SOCK_DGRAM(UDP数据报)/SOCK_RAW(原始套接字)。其中,SOCK_STREAM=1,SOCK_DGRAM=2,SOCK_RAW=3
  • proto:顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。常用的协议有,IPPROTO_TCP(=6)和IPPTOTO_UDP(=17),它们分别对应TCP传输协议、UDP传输协议。
  • 如:socket.getaddrinfo('www.baidu.com',80) --> 

    [(2, 2, 17, '', ('180.97.33.108', 80)), (2, 1, 6, '', ('180.97.33.108', 80)), (2, 2, 17, '', ('180.97.33.107', 80)), (2, 1, 6, '', ('180.97.33.107', 80))]

socket.getaddrinfo(host,  port, family=0, socktype=0, proto=0, flags=0)  
#根据给定的参数host/port,相应的转换成一个包含用于创建socket对象的五元组,  
#参数host为域名,以字符串形式给出代表一个IPV4/IPV6地址或者None.  
#参数port如果字符串形式就代表一个服务名,比如“http”"ftp""email"等,或者为数字,或者为None  
#参数family为地主族,可以为AF_INET  ,AF_INET6 ,AF_UNIX.  
#参数socketype可以为SOCK_STREAM(TCP)或者SOCK_DGRAM(UDP)  
#参数proto通常为0可以直接忽略  
#参数flags为AI_*的组合,比如AI_NUMERICHOST,它会影响函数的返回值  
#附注:给参数host,port传递None时建立在C基础,通过传递NULL。  
#该函数返回一个五元组(family, socktype, proto, canonname, sockaddr),同时第五个参数sockaddr也是一个二元组(address, port)  
# Echo server program  
import socket  
import sys  
  
HOST = None               # Symbolic name meaning all available interfaces  
PORT = 50007              # Arbitrary non-privileged port  
s = None  
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,  
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):  
    af, socktype, proto, canonname, sa = res  
    try:  
        #根据getaddrinfo()的返回信息初始化socket  
        s = socket.socket(af, socktype, proto)  
    except socket.error, err_msg:  
        print err_msg #回显异常信息  
        s = None  
        continue  
    try:  
        #sa是(host,port)的二元组  
        s.bind(sa)  
        #监听客户端请求  
        s.listen(1)  
    except socket.error, err_msg:  
        print err_msg  
        s.close()  
        s = None  
        continue  
    break  
if s is None:  
    print 'could not open socket'  
    sys.exit(1)  
      
conn, addr = s.accept()  
print 'Connected by', addr  
  
while 1:  
    data = conn.recv(1024)# 2)接受数据  
    if not data: break  
    conn.send(data)# 3)并返回2中接受到得数据  
conn.close()  
  
  
  
# Echo client program  
import socket  
import sys  
  
HOST = 'daring.cwi.nl'    # The remote host  
PORT = 50007              # The same port as used by the server  
s = None  
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):  
    af, socktype, proto, canonname, sa = res  
    try:  
        s = socket.socket(af, socktype, proto)  
    except socket.error, msg:  
        s = None  
        continue  
    try:  
        s.connect(sa)  
    except socket.error, msg:  
        s.close()  
        s = None  
        continue  
    break  
if s is None:  
    print 'could not open socket'  
    sys.exit(1)  
      
s.sendall('Hello, world')# 1)发送数据  
data = s.recv(1024)# 4)接受服务器回显的数据  
s.close()  
print 'Received', repr(data) #打印输出  






你可能感兴趣的:(python,getaddrinfo,python)