TCP协议、TCP套接字编程、TCP数据传输过程细节
- 1.3 TCP 传输方法(传输控制协议)
- [TCP——Transmission Control Protocol]
- 服务端客户端收发消息流程
- ** 练习01:如何让客户端退出但是服务端不退出,服务端可以继续处理下一个客户端连接?
- *** 注意:本质上,短连接形态还是和UDP传输模式一样,无法实现真正意义上的同步,如果一台客户端设备因为网速慢而没有及时结束收发消息,那么其他的客户端也无法连接到服务器.要想实现真正的同步,需要利用多进程处理
- ** 练习02:模拟一个问答机器人 从客户端输入问题发送给服务端,服务端根据问题中是否有关键字返回对应的回答
- TCP接收内容超过限定的最大可接受字节数会怎样?
- TCP==粘包问题==(多次发送的内容被一次接收)
- 1.3.5 ==TCP与UDP对比==
- 1.4 数据传输过程梳理
1.3 TCP 传输方法(传输控制协议)
[TCP——Transmission Control Protocol]
1.3.1 TCP传输特点
-
TCP是面向连接的传输服务
-
传输特征 : 提供了可靠的数据传输
-
可靠性指数据传输过程中无丢失,无失序,无差错,无重复。
-
-
可靠性保障机制(都是操作系统网络服务自动帮应用完成的):
- 在通信前需要建立数据连接 (UDP——陌拜 TCP——预约)
- 确认应答机制
- 通信结束要正常断开连接
-
三次握手(建立连接)
- 客户端向服务器发送消息报文请求连接
- 服务器收到请求后,回复报文确定可以连接
- 客户端收到回复,发送最终报文连接建立
- ACK SYN 确认变量
- ack 确认序列号
- seq 随机序列号
1.3.2 TCP服务端
1.3.2.1 创建套接字
sockfd=socket.socket(family,type)
功能:创建套接字
参数:family 网络地址类型 AF_INET表示ipv4
type 套接字类型 SOCK_STREAM 表示tcp套接字 (也叫流式套接字)
返回值: 套接字对象
## 参数type默认为SOCK_STREAM,
##因此创建时也可以直接写:
sockfd=socket.socket()
1.3.2.2 绑定地址 (与udp套接字相同)
sockfd.bind(addr)
功能: 绑定网络地址
参数: 二元元组 (ip,port) ('0.0.0.0',8888)
1.3.2.3 设置监听(使服务器可以被诸多客户端连接)
sockfd.listen(n)
功能 : 将套接字设置为监听套接字,确定监听队列大小
参数 : 监听队列大小
1.3.2.4 处理客户端连接请求(三次握手将在这一阶段完成)
connfd,addr = sockfd.accept()
功能: 阻塞等待处理客户端请求
返回值: connfd 客户端连接套接字
addr 连接的客户端地址
connfd——Connect file description 连接文件描述符
1.3.2.5 消息收发
data = connfd.recv(buffersize)
功能 : 接受客户端消息
参数 :每次最多接收消息的大小
返回值: 接收到的内容
n = connfd.send(data)
功能 : 发送消息
参数 :要发送的内容 bytes格式
返回值: 发送的字节数
1.3.2.6 关闭套接字 (与udp套接字相同)
connfd.close()
功能:关闭套接字
1.3.3 TCP客户端
- 创建TCP套接字
- 请求连接
sockfd.connect(server_addr)
功能:连接服务器
参数:元组 服务器地址
- 收发消息
注意: 为防止两端都阻塞,recv() send()要协调配合执行
- 关闭套接字(同上)
服务端客户端收发消息流程
1.3.4 TCP套接字细节
-
tcp连接中当一端退出,另一端如果阻塞在recv,此时recv会立即返回一个空字节串。
-
tcp连接中如果一端已经不存在,若仍试图通过send()向其发送数据则会产生BrokenPipeError
-
一个服务端可以同时连接多个客户端,也能够重复被连接
** 练习01:如何让客户端退出但是服务端不退出,服务端可以继续处理下一个客户端连接?
——让套接字对象的accept方法循环执行
[长连接形态:建立连接后,在一段时间内多次交互,而不需要重复的连接]
长连接缺点:在与一个客户端数据交互的循环里长期不退出,无法同时应对多个不同客户端的连接
解决:[短连接形态:建立连接后,一个客户端只处理一次数据的交互就断开连接,如果下次还想进行进行交互必须重新建立连接]
短连接缺点:每一次收发消息都要经历一次断开连接-重新建立连接的过程,效率低
*** 注意:本质上,短连接形态还是和UDP传输模式一样,无法实现真正意义上的同步,如果一台客户端设备因为网速慢而没有及时结束收发消息,那么其他的客户端也无法连接到服务器.要想实现真正的同步,需要利用多进程处理
** 练习02:模拟一个问答机器人 从客户端输入问题发送给服务端,服务端根据问题中是否有关键字返回对应的回答
定制关键字列表:
注意for循环处理问题关键字的逻辑:
TCP接收内容超过限定的最大可接受字节数会怎样?
——从接收缓冲区依次拿取
· 缓冲区的主要作用就是协调收发速度
· TCP套接字也叫流式套接字,其传输的内容是像水流一样连续且无边界的,recv()方法的阻塞取决于缓冲区内是否有可返回的内容,只要有内容,就会按照括号内限定的字节数依次返回
1.3.5 TCP与UDP对比
-
传输特征
- TCP提供可靠的数据传输,但是UDP则不保证传输的可靠性
- TCP传输数据处理为字节流,而UDP处理为数据包形式
- TCP传输需要建立连接才能进行数据传输,效率相对较低,UDP比较自由,无需连接,效率较高
-
套接字编程区别
- 创建的套接字类型不同
- TCP套接字会有粘包,UDP套接字有消息边界不会粘包
- TCP套接字依赖listen accept建立连接才能收发消息,UDP套接字则不需要
- TCP套接字使用send,recv收发消息,UDP套接字使用sendto,recvfrom
-
使用场景
- TCP更适合对准确性要求高,传输数据较大的场景
- 文件传输:如下载电影,访问网页,上传照片
- 邮件收发
- 点对点数据传输:如点对点聊天,登录请求,远程访问,发红包
- UDP更适合对可靠性要求没有那么高,传输方式比较自由的场景
- 视频流的传输: 如直播,视频聊天
- 广播:如网络广播,群发消息
- 实时传输:如游戏画面
- 在一个大型的项目中,可能既涉及到TCP网络又有UDP网络
- TCP更适合对准确性要求高,传输数据较大的场景
1.4 数据传输过程梳理
1.4.1 传输流程
- 发送端由应用程序发送消息,逐层添加首部信息,最终在物理层发送消息包。
- 发送的消息经过多个节点(交换机,路由器)传输,最终到达目标主机。
- 目标主机由物理层逐层解析首部消息包,最终到应用程序呈现消息。
1.4.2 TCP协议首部信息
-
源端口和目的端口 各占2个字节,分别写入源端口和目的端口。
-
序号 占4字节。TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。例如,一报文段的序号是301,而接待的数据共有100字节。这就表明本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400。
-
确认号 占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如,B正确收到了A发送过来的一个报文段,其序号字段值是501,而数据长度是200字节(序号501~700),这表明B正确收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
-
确认ACK(ACKnowledgment) 仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。
-
同步SYN(SYNchronization) 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1,因此SYN置为1就表示这是一个连接请求或连接接受报文。
-
终止FIN(FINis,意思是“完”“终”) 用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。