利用getaddrinfo()为服务器绑定端口
>>>from socket import getaddrinfo as gai
>>>gai('127.0.0.1','smtp',0,socket.SOCK_STREAM,0)
>>>[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 0, '', ('127.0.0.1', 25))]
使用getaddrinfo()连接服务
gai('www.baidu.com','http',0,socket.SOCK_STREAM,0,socket.AI_ADDRCONFIG|socket.AI_V4MAPPED|socket.CANONNAME)
参数:
AI_ADDRCONFIG:将会过滤掉无法连接的
AI_V4MAPPED:若本机只有IPV6,服务为IPV4,将会将IPV4地址重新编码为可用的IPV6地址
CANONNAME:将会返回DNS反向查询(ip->主机名)、但是返回的主机名是服务端自己定义的,可能是无意义的东西,例如下方百度返回的(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 0, 'www.a.shifen.com', ('14.215.177.38', 80))
代码中使用:
import socket
import argparse #命令行解析参数
def connect(host_ip):
try:
infolist = socket.getaddrinfo(
host_ip,
'http',
0,
socket.SOCK_STREAM,
0,
socket.AI_ADDRCONFIG|socket.AI_V4MAPPED|socket.AI_CANONNAME
)
except:
pass
info = infolist[0] # 取第一个
sock = socket.socket(*info[0:3]) # [<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 0] 前3个用于创建套接字
address = info[4] # ('14.215.177.39', 80)用于连接的ip地址
try:
sock.connect(address)
except:
pass
else:
print("连接成功,信息{}".format(info))
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='connect host or ip')
parser.add_argument('hostname',)
connect(parser.parse_args().hostname)