epoll多路复用
为了实现及时聊天,即两方可以任意向对方发送连续的多条消息的功能,需要使用epoll。在内核中,socket对象缓冲区recv()、标准输入缓冲区input()都分配了一段内存,内存对应一个整型编号(数组下标),这个编号就是文件描述符file describer。
我们创建epoll对象,注册要监控的fd和事件类型,让epoll去监控哪几个缓冲区发生了指定事件,以列表的形式主动报告给用户进程。
1.使用epoll编写即时聊天
服务器代码
1 |
|
2.使用epoll实现聊天室
实现多人聊天,
- 新增客户端断开后可以再次连接,服务器端不会退出(epoll解除绑定、关闭client对象);
- 新建一个client列表,存储每个客户端对象,循环遍历查看缓冲区有无数据;
- 文件协议设计,聊天室增加用户名功能。
3.持续发送多个文件,协议设计
使用TCP连接发送文件时,首先要以字节流形式传送,如果持续发送多个文件,文件名1+文件1内容+文件名2+文件2内容+。。。存在粘包问题,两次发送的报文挨在一起,分不开。
我们采用开火车的方式解决粘包,如下所示。
- 小火车
- 火车头填写长度:字节数,python需pack为4字节整型数
- 火车车厢填写内容:字符串字节流
文件名 | 文件内容 | |
---|---|---|
车头 | 文件名长度(4B) | 文件内容总长度(4B) |
车厢 | 文件名 | 文件内容 |
Python的struct模块,提供了一种机制,能将int、float等基本数据类型打包成字符串(实际上相当于其他语言的字节流),可以在网络上传输,而接收端也可以通过解包还原出初始的数据。
pack(fmt, var1, var2,…)
按照给定的格式(fmt),把数据封装成字符串(实际上类似于C结构体的字节流);unpack(fmt, string)
按照给定的格式(fmt)解析字节流(string),返回解析出来的tuple元组;calcsize(fmt)
计算给定的格式(fmt)占用多少字节的内存
4. 总结
- 写代码的时候对不确定的代码实现效果,自己动手写一个简单的例子验证一下就可以,这样就不至于代码写了一大堆,不确定错误在哪里。
epoll多路复用
http://paopaotangzu.icu/2024/08/22/3.epoll多路复用/