python网络编程详解

最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容,结合自己后台开发的经验,写下这篇文章,一方面是为了帮助有需要的人,更重要的是方便自己整理思路,加深理解。

理论基础

OSI网络模型

python网络编程详解_第1张图片

OSI模型是一个七层模型,实际工程中,层次的划分没有这么细致。一般来说,物理层和数据层对应着硬件和设备驱动程序,例如网卡和网卡驱动。传输层和网络层由操作系统内核实现,当用户进程需要通过网络传输数据,通过系统调用的方式让内核将数据封装为相应的协议格式,进而调用网卡驱动传输数据。顶上三层对应具体的网络应用协议:FTP、HTTP等,这些应用层协议不需要知道具体的通信细节。

传输层

在实际工程中,我们常用的应用层服务(例如:HTTP服务、数据库服务、缓存服务)通信的直接底层就是传输层,下图是一些常用命令涉及的通信协议。

python网络编程详解_第2张图片

IPv4(Internet Protocol version 4)全称是网际协议版本4,它使用32地址,平时常说的IP协议就是指IPv4,类似于192.168.99.100的地址可以看成4位256进制数据,也就是32网络地址。但随着网络设备爆炸式增长,32地址面临这用完的风险,IPv6(Internet Protocol version 6)应运而生。IPv6使用128位地址,但IPv4地址耗尽的问题有了新的解决方案,目前普遍使用的还是IPv4,IPv6全面取代IPv4还有很长的距离。

UDP (User Datagram Protocol),全称用户数据报协议。UDP提供面向无连接的服务,客户端和服务端不存在任何长期的关系。UDP不提供可靠的通信,它不保证数据报一定送达,也不保证数据包送达的先后顺序,也不保证每份数据报只送达一次。虽然UDP可靠性差,但是消耗资源少,适用在网络环境较好的局域网中,例如不需要精确统计的监控服务(eg: Statsd)。由于使用了UDP,客户端每次打点统计只需要一次发送UDP数据报的IO开销,服务性能损失很小,而且在内网环境数据包一般都能正常到达服务端,也能保证较高的可行度。

TCP(Transmission Control Protocl),全称传输控制协议。和UDP相反,TCP提供了面向连接的服务,而且提供了可靠性保障。平常我们使用的应用层协议,例如HTTP,FTP等,几乎都是建立在TCP协议之上,深入了解TCP的细节对于开发高质量的后台开发和客户端开发都有很好的借鉴意义。下面开始重点介绍TCP协议的细节。

TCP协议

状态转换

为了提供可靠的通信服务,TCP通过三次分节建立连接,四次分节关闭连接,心跳检查判断连接是否正常,因此需要记录连接的状态,TCP一共定义了11种不同的状态。

python网络编程详解_第3张图片

通过netstat命令可以查看所有的tcp状态。

python网络编程详解_第4张图片

三路握手

python网络编程详解_第5张图片

在三路握手之前,服务器必须准备好接收外来的连接。这通常通过调用bindlisten完成被动打开,此时服务进程有一个套接字处于LISTEN状态。在客户端发通过调用connect送一个SYN分节后,服务进程必须确认(ACK)此分节,同时也发送一个SYN分节,这两步在同一分节中完成,通过上面的转台扭转图,可以知道服务进程中会生成一个处于SYN_RCVD状态的套接字。当再次收到客户端的ACK分节后,服务端的套接字状态转变为ESTABLISHED。

客户端通过connect函数发起主动打开,在此之前客户端套接字状态为CLOSED。调用connect导致客户TCP发送一个SYN分节,此时套接字状态有CLOSED变为SYN_SENT,在收到服务器的SYN和ACK后,客户端socket再发送ACK分节,套接字状态变为ESTABLISHED,此时connect返回。

备注:SYN分节中除了有序列号之外,还会有最大分节大小、窗口规模选项、时间戳等TCP参数,具体可以参考协议详细规定。

终止连接

python网络编程详解_第6张图片

上图展示了客户端执行主动关闭的情形,实际上无论客户端还是服务器,都可以执行主动关闭。一般情况下客户端执行主动关闭较多,所以使用客户端主动关闭为例讲解。

客户端调用

你可能感兴趣的:(网络,udp,tcp/ip,开发语言,深度学习)