为了深入学习web框架,现在开始底层socket编程的学习,以便打好基础。
python socket模块提供了一个底层的C API,可以使用BSD套接字接口实现网络通信。
今天先学习寻址、协议簇和套接字类型的相关知识。
什么是套接字呢?
套接字是程序在本地或者通过互联网来回传递数据时所用通信通道的一个端点。
套接字包含两个主要属性,用于控制如何发送数据:
- 地址簇:控制OSI网络层协议
- 套接字类型:控制传输层协议
Python支持三种地址簇:
- AF_INET: 用于IPv4 寻址
- AF_INET6: 用于IPv6寻址
- AF_UNIX: 用于UNIX域套接字
套接字类型主要是以下两种:
- SOCK_DGRAM:对应UDP协议
- SOCK_STREAM:对应TCP协议
UDP和TCP的区别:
- TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量- 数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。
- UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
在网络中查找主机
要查找当前主机的名字,可以使用gethostname()
import socket
socket.gethostname()
所返回的名字取决于当前系统的网络设置,在不同的网络返回的名字可能不一样。
反过来,可以使用gethostbyname()
来通过主机名获取对应的IP地址:
import socket
如果没有找到对应的IP地址,将抛出socket.error
异常。
如果需要获取更多信息,如别名和所有主机IP地址,可以使用gethostbyname_ex()
。
如果需要根据某个IP获取其对应的主机名等信息,可以使用gethostbyaddr()
,该函数返回一个元组,包括了主机名,别名以及IP地址。
查找服务信息
除了IP地址之外,每个套接字地址还包括一个整数端口号,一次只能有一个套接字使用该地址的端口。
有些端口号已经预先分配给某个特定协议,例如SMTP使用25端口,HTTP使用80端口。
网络服务的端口号和标准名可以使用getservbyname()
查找。
socket.getservbyname("http")
要完成逆向服务端口查找,可以使用getservbyport()
socket.getservbyport(80)
可以使用getprotobyname()
获取分配给一个传输协议的端口号:
socket.getprotobyname("imap")
socket.getprotobyname("tcp")
查找服务器地址
使用getaddrinfo()
可以将一个服务的基本地址转换为一个元组列表。
"https")