tcp协议 和 udp协议
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
socket的基本使用
TCP 的socket — 基础对话版
1 | # server端 |
1 | # client端 |
循环对话版
1 | # server端 |
1 | # client端 |
时间戳转换
1 | ip_port = ('127.0.0.1',8090) |
1 | # client端 |
UDP 的socket — 基础对话版
1 | # server |
1 | # client |
在udp的消息通信的时候:
- 不需要进行监听 (listen)
- 不需要建立链接 (accept)
- 在启动服务之后,只能被动的等到客户端发送消息过来
- 客户端发送消息的同时,还会带着地址信息过来
- 服务端进行消息服务的时候,不仅需要发送消息,还需要带着对方的地址回去
UDP 实现简易QQ
1 | # server |
1 | # client |
UDP 实现简易时间同步
1 | # server |
1 | # client |
黏包现象
subprocess 远程执行命令
1 | import subprocess |
TCP的黏包现象
1 | # 在server端下发命令 |
1 | # 在client端接收命令并执行返回 |
UDP的黏包现象
1 | # server |
1 | # client |
触发黏包
会发生黏包的两种情况
- 发送方的缓存机制
发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据很小,会合到一起,产生粘包)
1 | # server |
1 | import socket |
- 接收方的缓存机制
1 | # server |
1 | # clietn |
总结黏包现象
黏包现象只发生在tcp协议中:
- 从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。
- 实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
解决黏包
发送消息长度
- 黏包问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个循环接收完所有数据。
- 存在的问题:
程序的运行速度远快于网络传输速度,所以在发送一段字节前,先用send去发送该字节流长度,这种方式会放大网络延迟带来的性能损耗。
1 | # server |
1 | # client |
进阶方法—使用struct模块
1 | # struct模块作用:把一个类型,如数字,转成固定长度的bytes |
1 | # server |
1 | # client |
使用struct解决黏包
借助struct模块,我们知道长度数字可以被转换成一个标准大小的4字节数字。因此可以利用这个特点来预先发送数据长度。
我们还可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了)
实现大文件上传和下载
1 | # server 接收端 |
1 | # client 发送端 |
自定制报头 发送数据
1 | # server |
1 | # client |