传输层
传输层概述
程序员一般是利用传输层的提供的接口进行网络编程。
传输层属于用户部分的最底层,通信的最高层。
传输层的作用:管理端到端的通信连接。
传输层解决的问题是:通过虚拟的互连网络连接的两个终端设备如何进行通信。也就是进程与进程间的通信,这里称为网络通信。
在操作系统中学习到的进程通信方式有:共享内存、Unix域套接字。
区别:
网络通信:跨网络,跨设备的进程通信
共享内存、套接字:只能实现单机上进程间的通信
端口的概念
使用端口(Port)来标记不同的网络进程
端口(Port)使用16比特位表示(0~65535)
UDP协议
UDP协议的概念:
UDP(User Datagram Protocol: 用户数据报协议)
UDP是一个非常简单的协议
UDP协议首部:
UDP协议的特点:
- UDP是无连接协议。计算机之间发送数据时,不需要提前建立连接,想发送时直接发送。
- UDP不能保证可靠的交付数据。想发就发,无法保证数据在网络中是否丢失。
- UDP是面向报文传输的。数据报是指应用层传输过来的一个完整的数据。对于应用传输的数据报,上层传下来的数据报,不合并,不拆分,不处理。
因此数据报直接决定了UDP数据报文的长度。 - UDP没有拥塞控制。不能感知网络是否拥塞,即使拥塞也会尽量把数据传输出去
- UDP的首部开销很小。
TCP协议
TCP协议的概念:
TCP(Transmission Control Protocol: 传输控制协议)
TCP协议是计算机网络中非常复杂的一个协议
TCP协议首部:
- 序号:0~2^32-1;一个字节一个序号;数据首字节序号。
- 确认号:0~2^32-1;一个字节一个序号;期望收到数据的首字节序号。确认号为N则表示N-1序号的数据都已经收到。
- 数据偏移:占4位:0~15,单位为:32位字;数据偏离首部的距离。
- TCP标记:占6位,每位各有不同意义。
- 窗口:占16位:0~2^16-1;窗口指明允许对方发送的数据量。
- 紧急指针:紧急数据(URG=1时启动);指定紧急数据在报文的位置。
- TCP选项:最多40字节;支持未来的拓展。
TCP协议的特点:
- TCP是面向连接的协议。必须建立连接之后才能发送数据。
- TCP的一个连接有两端(点对点通信)。
- TCP提供可靠的传输服务。
- TCP协议提供全双工的通信。 全双工是指两个计算机都可以同时往连接里发送数据或者接收数据。
- TCP是面向字节流的协议。字节流是指流入进程或流出进程的字节序列。TCP协议把应用层传输下来的数据看成一系列字节流。有可能拆分成两次传输,有可能合并或拆分
TCP协议的可靠传输
可靠传输的基本原理
1、停止等待协议
发送方发送完一个消息之后就停止发送新的消息,等待接收方确认,确认完成再发送新的消息。发送方和接收方都是处于停止 - 等待 - 停止的过程。
出差错的情况:发送的消息在路上丢失了;确认的消息在路上丢失了;确认的消息很久才到。
每发送一个消息,都需要设置一个定时器。
在这些情况下,停止等待协议可以通过超时重传保证可靠传输。
停止等待协议是最简单的可靠传输协议
停止等待协议对信道的利用效率不高
2、连续ARQ协议
ARQ(Automatic Repeat reQuest:自动重传请求),可以实现批量发送和确认。
累计确认:如果收到了某个消息,就表示这个消息之前的消息都收到了,滑动窗口向前推动。
TCP协议的可靠传输
TCP的可靠传输基于连续ARQ协议
TCP的滑动窗口以字节为单位
选择重传需要指定需要重传的字节,指定的是边界
每一个字节都有唯一的32位序号
TCP协议的流量控制
流量控制指让发送方发送速率不要太快
流量控制是使用滑动窗口来实现的
当接受方通知发送方下一次窗口为100的消息丢失时,发送方由于没有收到消息会一直等待,从而造成死锁为什么会发生呢,因为TCP协议的可靠传输只对数据传输可靠,对窗口消息不可靠。解决办法:坚持定时器。
坚持定时器
当接收到窗口为0的消息,则启动坚持定时器。
坚持定时器每隔一段时间发送一个窗口探测报文。
TCP协议使用滑动窗口实现流量控制
坚持定时器的作用
TCP协议的拥塞控制
流量控制和拥塞控制的区别:
流量控制考虑点对点的通信量的控制
拥塞控制考虑整个网络,是全局性的考虑
判断拥塞的方法:报文超时则认为是拥塞
慢启动算法:指数增长
拥塞避免算法:线性增长
TCP连接的三次握手(连接建立)
关键的TCP标记:
ACK:确认位,ACK=1,确认号才生效
SYN:同步位,SYN=1 表示连接请求报文
FIN:终止位,FIN=1 表示释放连接
三次握手的过程:
建立连接,同步各自序号
为什么发送方要发出第三个确认报文呢?
已经失效的连接请求报文传送到对方,会引起错误。超时重传时可能造成两次TCP连接。
TCP连接的四次挥手(连接释放)
等待计时器(TIME-WAIT):
等待的时间为2MSL
MSL(Max Segment Lifetime): 最长报文段寿命
MSL建议设置为2分钟
为什么需要等待2MSL?
1、如果最后一个报文没有确认,无法确保发送方的ACK可以到达接收方,若2MSL时间内没有收到,则接收方会重发,重复进行第三次挥手。
2、确保当前连接的所有报文都已经过期
TCP协议的四个定时器
套接字与套接字编程
使用端口(Port)来标记不同的网络进程。
端口(Port)使用16比特位表示(0~65535)。
套接字是IP与端口号的组合,一个IP可以有多个套接字,因为可以和不同的端口号组合。
套接字(Socket)是抽象概念,表示TCP连接的一端。
通过套接字可以进行数据发送或接收。
客户端和服务端进行TCP连接的过程:
代码:
server.py
# -*- encoding=UTF-8 -*-
import socket
def server():
# 创建socket
s = socket.socket()
host = '127.0.0.1'
post = 6666
# 绑定套接字
s.bind((host,post))
# 监听
s.listen(5)
while True:
c, addr = s.accept()
print('connect addr:', addr)
c.send('welcome to server!')
c.close()
if __name__ == '__main__':
server()
client.py
# -*- encoding=UTF-8 -*-
import socket
def client(i):
# 创建socket
s = socket.socket()
# 连接套接字
s.connect(('127.0.0.1', 6666))
print('Receive message: %s, client: %d'%(s.recv(1024), i))
s.close()
if __name__ == '__main__':
for i in range(10):
client(i)
计算机网络的网络套接字 与 操作系统的域套接字 比较
网络套接字:不管是跨计算机还是同一个计算机,如果使用网络套接字进行数据传输,数据都会经过下面的协议栈一趟,才能回到用户界面。
域套接字是通过域套接字文件进行数据传输的。使用这种方法,数据不需要通过协议栈。单机通信推荐域套接字,处理流程简单,系统消耗小。