基本概念
IP地址与端口
IP地址
用来标识网络中一个通信实体的地址。通信时可以是计算机、路由器等。
IP地址实际上是一个32位的整数,成为TPv4,一字符串标识的IP地址如192.168.0.1是加上十八32位的整数按8位分组后地表示,目的是为了便于阅读。
IPv6是一个128位的整数,以字符串的标识类似于20001:0db8:85a3:0042:1000:8a2e:0370:7334。
注意事项:
127.0.0.1是本机地址
192.168.0.0-192.168.255.255为私有地址,分注册地址,专门用于机构内部使用。
端口
通过端口可以在一个主机上运行多个网络应用程序。
端口的表示是一个16位的二进制真大户,对应的十进制为0-65535。
网咯通信协议
OSI模型
计算机通信开放系统互连(open systems interconnection)模型用于描述一个网络中各个协议层。这是一个七层模型,下图给出了它与网际协议族的近似映射:
- 数据链路层和物理层是随系统提供的设备驱动程序和网络硬件。通常只需知道数据链路的某些特性(如1500字节以太网的MTU大小)。
- 网络层由IPv4和IPv6两个协议处理。传输层有TCP或UDP(其间有间隙,表明网络应用可以使用原始套接字绕过传输层,甚至网络层)。
- OSI模型的顶上三层是浏览器、FTP服务器、Telnet客户等网络应用所在的层,对于网际协议,这三层协议几乎没有区别。
- 套接字编程接口是从顶上三层进入传输层的接口。顶上三层通常构成用户进程,底下四层通常作为操作系统内核的一部分提供。
TCP/IP协议族
虽然协议族被称为“TCP/IP”,但除了这两个主要协议外,还有许多其他成员。部分如下:
IPv4——网际协议版本4(Internet Protocol version 4)。使用32位地址。
IPv6——网际协议版本6(Internet Protocol version 6)。使用128位地址以应对因特网的爆发性增长。
TCP——传输控制协议(Transmission Control Protocol)。TCP是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字(stream socket)。TCP关心确认、超时和重传之类的细节。
UDP——用户数据报协议(User Datagram Protocol)。UDP是一个无连接协议。UDP套接字是一种数据报套接字(datagram socket)。UDP数据报不能保证最终到达它们的目的地。
ICMP——网际控制消息协议(Internet Control Message Protocol)。ICMP处理在路由器和主机之间流通的错误和控制消息。ping和traceroute程序使用此协议。
ARP——地址解析协议(Address Resolution Protocol)。ARP把一个IPv4地址映射成一个硬件地址(如以太网地址)。ARP通常用于广播网络。
RARP——反向地址解析协议(Reverse Address Resolution Protocol)。RARP把一个硬件地址映射成一个IPv4地址。
OSI与TCP/IP的比较:
分层结构
OSI参考模型与TCP/IP协议都采用了分层结构,都是基于独立的协议栈的概念。OSI参考模型有7层,而TCP/IP协议只有4层,即TCP/IP协议没有了表示层和会话层,并且把数据链路层和物理层合并为网络接口层。不过,二者的分层之间有一定的对应关系
标准的特色
OSI参考模型的标准最早是由ISO和CCITT(ITU的前身)制定的,有浓厚的通信背景,因此也打上了深厚的通信系统的特色,比如对服务质量(QoS)、差错率的保证,只考虑了面向连接的服务。并且是先定义一套功能完整的构架,再根据该构架来发展相应的协议与系统。
TCP/IP协议产生于对Internet网络的研究与实践中,是应实际需求而产生的,再由IAB、IETF等组织标准化,而并不是之前定义一个严谨的框架。而且TCP/IP最早是在UNIX系统中实现的,考虑了计算机网络的特点,比较适合计算机实现和使用。
连接服务
OSI的网络层基本与TCP/IP的网际层对应,二者的功能基本相似,但是寻址方式有较大的区别。
OSI的地址空间为不固定的可变长,由选定的地址命名方式决定,最长可达160byte,可以容纳非常大的网络,因而具有较大的成长空间。根据OSI的规定,网络上每个系统至多可以有256个通信地址。
TCP/IP网络的地址空间为固定的4byte(在目前常用的IPV4中是这样,在IPV6中将扩展到16byte)。网络上的每一个系统至少有一个唯一的地址与之对应。
传输服务
OSI与TCP/IP的传输层都对不同的业务采取不同的传输策略。OSI定义了五个不同层次的服务:TP1,TP2,TP3,TP4,TP5。TCP/IP定义了TCP和UPD两种协议,分别具有面向连接和面向无连接的性质。其中TCP与OSI中的TP4,UDP与OSI中的TP0在构架和功能上大体相同,只是内部细节有一些差异。
应用范围
OSI由于体系比较复杂,而且设计先于实现,有许多设计过于理想,不太方便计算机软件实现,因而完全实现OSI参考模型的系统并不多,应用的范围有限。而TCP/IP协议最早在计算机系统中实现,在UNIX、Windows平台中都有稳定的实现,并且提供了简单方便的编程接口(API),可以在其上开发出丰富的应用程序,因此得到了广泛的应用。TCP/IP协议已成为目前网际互联事实上的国际标准和工业标准。
TCP/UDP
用户数据报协议(UDP)
应用进程往一个UDP套接字写入一个消息,该消息被封装到一个UDP数据报,该UDP数据报进而又被封装到一个IP数据报,然后发送到目的地。UDP不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数据报只到达一次。
- 每个UDP数据报都有一个长度。如果一个数据报正确地到达其目的地,那么该数据报的长度将随数据一道传递给接收端应用进程。而TCP是一个字节流(byte-stream)协议,没有任何记录边界,这一点不同于UDP。
- UDP提供无连接(connectionless)的服务。举例来说,一个UDP客户可以创建一个套接字并发送一个数据报给一个给定的服务器,然后立即用同一个套接字发送另一个数据报给另一服务器。同样地,一个UDP服务器可以用同一个UDP套接字从若干个不同的客户接收数据报,每个客户一个数据报。
传输控制协议(TCP)
TCP提供客户与服务器之间的连接,TCP客户先与某个给定服务器建立一个连接,再跨该连接与那个服务器交换数据,然后终止这个连接。
- TCP提供可靠性。当TCP向另一端发送数据时,它要求对端返回一个确认。如果没收到确认,TCP就自动重传数据并等待更长时间,在数次重传失败后,TCP才放弃。
- TCP含有动态估算客户与服务器之间的往返时间(round-trip time,RTT)的算法。以便它知道等待一个确认需要多长时间。
- TCP通过给其中每个字节关联一个序列号对所发送的数据进行排序(sequencing)。举例来说,假设一个应用写2048字节到一个TCP套接字,导致TCP发送两个分节(分节是TCP传递给IP的数据单元):第一个分节所含数据的序列号为11024,第二个分节所含数据的序列号为10252048。如果这些分节非顺序到达,接收端TCP将先根据它们的序列号重新排序,再把结果数据传递给接收应用。如果接收端TCP接收到来自对端的重复数据(网络通信拥挤重传时),可以根据分节序列号判定数据是重复的,从而丢弃重复数据。
- TCP提供流量控制(flow control)。 TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为“通告窗口(advertised window)”。在任何时刻,该窗口指出接收缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。通告窗口大小减少到0是可能的:当TCP对应某个套接字的接收缓冲区已满,导致它必须等待应用从该缓冲区读取数据时,方能从对端再接收数据。
- TCP连接是全双工的(full-duplex)。这意味着在一个给定的连接上应用可以在任何时刻在进出两个方向上既发送数据又接收数据。
TCP选项
- MSS选项——发送SYN的TCP一端使用本选项通告对端它的最大分节大小(maximum segment size)即MSS,也就是它在本连接的每个TCP分节中愿意接受的最大数据量。可使用TCP_MAXSEG套接字选项提取和设置这个TCP选项。
- 窗口规模选项——TCP连接任何一端能够通告对端的滑动窗口大小(接收缓冲区大小),因为在TCP首部中缓冲区大小字段占16位,所以它的最大值是65535。对于一些情况(光纤高速通信网络,或者是卫星长连接网络)来说需要使用更大的滑动窗口,这时会使用扩展的滑动窗口大小(要求有更大的窗口以获得尽可能大的吞吐量)。
- 时间戳选项——对于高速网络连接是必要的,可防止由暂时的路由原因造成的迷途的分组可能造成的数据损坏。
TCP的首部
- 每个TCP段都包含源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。
- 在TCP首部中有 6个标志比特。它们中的多个可同时被设置为 1。
- URG 紧急指针(urgent pointer)有效
- ACK 确认序号有效
- PSH 接收方应该尽快将这个报文段交给应用层
- RST 重建连接
- SYN 同步序号用来发起一个连接
- FIN 发端完成发送任务
TCP状态转换
TCP建立一个连接需3个分节,终止一个连接则需4个分节,涉及连接建立和连接终止的操作可以用状态转换图来说明。TCP为一个连接定义了11中状态,并且规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态。(可使用netstat去监视状态变化)
- 自ESTABLISHED状态引出的两个箭头处理连接的终止。如果某个应用进程在ESTABLISHED状态期间接收到一个FIN(被动关闭),那就转换到CLOSE_WAIT状态;如果在接收到一个FIN之前调用close(主动关闭),那就转换到FIN_WAIT_1状态。
一个完整的TCP连接所发生的实际分组交换情况包括:连接建立、数据传送和连接终止。下图展示了分组交换过程中每个端点所经历的TCP状态,客户端通告一个值为536的MSS(最小重组缓冲区大小),服务器通告一个值为1460的MSS(以太网上IPv4的典型值):
WAIT_TIME状态
执行主动关闭的一端经历了这个状态。该端点停留在这个状态的持续时间是最长分节生命期(maximum segment lifetime, MSL)的两倍,有时称为2MSL。任何TCP实现都必须为MSL选择一个值,RFC 1122建议值为2分钟,源自Berkeley的实现传统上改用30秒。这意味着TIME_WAIT状态的持续时间在1分钟到4分钟之间。
网络中,一个TCP分节可能由路由异常(某个路由器崩溃或某两个路由器之间的某个链路断开时)导致”迷途“,迷途的TCP分节自其开始旅程起需要最多MSL秒内路由方能修复。如果在迷途期间,发送端TCP超时并重传TCP分节,重传的TCP分节和之前迷途的TCP分节都可能被正确送达目的地。TCP必须正确处理这种情况。
以图”TCP连接的分组交换“为例,如果上述情况发生在一个TCP连接终止序列4个分节中的最终的ACK分节上时,导致客户端最终的ACK丢失,服务端将重新发送它的最终的FIN,因此客户端必须维护状态信息(TIME_WAIT)等待路由修复,以允许它重新发送最终的ACK。(TCP要可靠地实现全双工连接的终止,必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。)本例也说明了为什么执行主动关闭的那一端是处于TIME_WAIT状态的一端:因为可能不得不重传最终那个ACK的就是执行主动关闭的那一端。
假设12.106.32.254:1500和206.168.112.219:21之间有一个TCP连接,当关闭这个连接时出现了上述情况,TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,从而被误解成属于同一连接的某个新的化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。既然TIME_WAIT状态的持续时间是MSL的2倍,这就足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MLS秒也被丢弃。通过这个规则就能保证,每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已在网络中消逝了。
套接字编程
socket()函数介绍
在python中,通常用一个Socket表示“打开了一个网络连接”,语法格式如下:
socket.socket([family[,type[,proto]]])
其中参数family:套接字家族可以使AF_UNIX或者AF_INET;
type:套接字欸ing可以根据是面向连接的还是非连接分为SOC_STREAM或SOCK_DGRAM;
protocol:一般不填默认为0。
面向连接的使用TCP协议,示例代码:
tcpSocket=socket.socket(AF_INET,SOCK_STREAM)
无连接的使用UDP协议,示例代码:
udpSocket=socket.socket(AF_INET,SOCK_DGRAM)
UDP编程
TCP创建的是可靠连接,并且双方都可以一流的形式发送数据。相对TCP,UDP则是面向无连接的协议。使用UDP时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发送数据包。但是,无法知道能不能到达。虽然数据不可靠,但他的优点是和TCP相比,速度快,对于不要求可靠到达的护具ÿ