五个必要的设定
address family
一般是AF_INET, IPV6就是AF_INET6
socket type
TCP选SOCK_STREAM,UDP选SOCK_DGRAM
Protocol
Socket()接口的第三个参数有用到,一般填0,具体含义暂时不知道,好像是使用TCP还是UDP协议
IP address
UDP or TCP port number:
所有的套接字接口都会一定会用到这几个参数,例如socket.socket 和bind,就需要五个类型的参数设定了。
主动连接方,免去考虑使用IPV4还是IPV6,getaddrinfo()
>>> from socket import getaddrinfo
>>> infolist = socket.getaddrinfo('gatech.edu', 'www')
>>> pprint(infolist)
[(2, 1, 6, '', ('130.207.244.244', 80)), #得到了
(2, 2, 17, '', ('130.207.244.244', 80))]
>>> ftpca = infolist[0]
>>> ftpca[0:3]
(2, 1, 6)
>>> s = socket.socket(*ftpca[0:3])
>>> ftpca[4]
('130.207.244.244', 80)
>>> s.connect(ftpca[4])
ftpca 是一个缩写,表示”family, type, protocol, canonicalname, and address”
这样可以直接获取目标的配置信息,不需要进行额外的判断,直接进行连接操作。
getaddrinfo()参数说明和使用
以下来自 python331.chm
接口声明:socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)
接口返回值: (family, type, proto, canonname, socketname)
参数family
socket.AF_UNIX
socket.AF_INET
socket.AF_INET6
These constants represent the address (and protocol) families, used for the first argument to socket(). If the AF_UNIX constant is not defined then this protocol is unsupported. More constants may be available depending on the system.
参数type
socket.SOCK_STREAM
socket.SOCK_DGRAM
socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET
These constants represent the socket types, used for the second argument to socket(). More constants may be available depending on the system. (Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.)
参数Protocol
指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型(上一个参数类型)决定应使用的传输层协议。
在VC++里面的类型有(ws2def.h)
#define IPPROTO_IP 0 /* dummy for IP */
#define IPPROTO_ICMP 1 /* control message protocol */
#define IPPROTO_IGMP 2 /* internet group management protocol */
#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_PUP 12 /* pup */
#define IPPROTO_UDP 17 /* user datagram protocol */
#define IPPROTO_IDP 22 /* xns idp */
#define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */
#define IPPROTO_RAW 255 /* raw IP packet */
#define IPPROTO_MAX 256
Python暂时不知道,socket.SOL_UDP
参数flags
在VC++中的定义和说明(ws2def.h)
#define AI_PASSIVE 0x00000001 // Socket address will be used in bind() call
#define AI_CANONNAME 0x00000002 // Return canonical name in first ai_canonname
#define AI_NUMERICHOST 0x00000004 // Nodename must be a numeric address string
#define AI_NUMERICSERV 0x00000008 // Servicename must be a numeric port number
#define AI_ALL 0x00000100 // Query both IP6 and IP4 with AI_V4MAPPED
#define AI_ADDRCONFIG 0x00000400 // Resolution only if global address configured
#define AI_V4MAPPED 0x00000800 // On v6 failure, query v4 and convert to V4MAPPED format
#define AI_NON_AUTHORITATIVE 0x00004000 // LUP_NON_AUTHORITATIVE
#define AI_SECURE 0x00008000 // LUP_SECURE
#define AI_RETURN_PREFERRED_NAMES 0x00010000 // LUP_RETURN_PREFERRED_NAMES
#define AI_FQDN 0x00020000 // Return the FQDN in ai_canonname
#define AI_FILESERVER 0x00040000 // Resolving fileserver name resolution
DNS服务
搜寻域名对应的socketName时,一般先查找本地的hosts或者相应的缓存,如果上面两个都没有找到的话,那就通过DNS查找,通过DNS查找比较慢。第一次访问的时候速度比较慢,后面由于有了相应的缓 存,并且没有失效的话,那就不会通过DNS查找了。
Default port: 53
Libraries: PyDNS, dnspythonk, python3用不了
使用上面的两个第三方库,可以通过查找DNS服务,查找MX(Mail Exchanger,邮件交换)记录来得到邮件地址所对应的邮件服务器的地址。
Zeroconf and Dynamic DNS
当缺失DNS服务器时,可以使用另外两种技术来获取域名对应的socketname, Zeroconf 和 Dynamic DNS。
其他
1.判断本地库是否具有IPv6的特性
>>> import socket
>>> socket.has_ipv6
True
2. 查看一个对象的方法和属性
>>> import socket
>>> dir(socket)
['AF_APPLETALK', 'AF_DECnet', 'AF_INET'…