# 计算机网络 Project-小说阅读器
# 一、概述
本文为 2019 秋计算机网络课程 Socket 编程实验报告,我选择了小说阅读器作为实现对象。本节主要阐述任务要求、项目概述及文章框架。
## 1.1 任务要求
本任务的要求分为两个部分: 总体要求和具体项目要求。
总体要求:设计一个具体的协议(建议是应用层协议),采用标准 Socket API 编程来实现协议的功能。
### 1.1.1 简单的小说阅读器设计:
服务器端保存小说文本(txt 格式的即可)
#### 1.1.1 客户可以打开对应的文本,翻页,翻章,跳页,书签,下载,关闭等
建议最好有图形界面,因为是 txt 格式,所谓的“页”可以通过规定每次内容包含的字节来规定
## 1.2 项目特点
本小说阅读器使用 Python 编写,图形界面使用 Tkinter 库,信息传输依赖标准的 Socket API。提供的功能有:用户注册、用户登录、小说阅读、小说下载。对所有使用 Socket 传输的信息都实现了加密,保证信息安全。在服务器端采用多线程设计,可长时间运行并支持同时支持多个客户端。
## 1.3 文章结构
本文第二节会说明小说阅读器的实现细节,包含传输协议(及加密算法)、服务器、客户端、重点功能实现和错误处理五个部分,第三部分则展示小说阅读器的最终运行效果,最后一部分进行总结,阐述还可以改进的地方以及本次实验的收获。
实现细节本节会详细说明小说阅读器实现各个部分的关键点。
## 1.4 传输协议
### 1.4.1 由于传输协议为客户端与服务器通用,所以我将所有协议内容放在单独的文件夹
“protocol”下。鉴于小说阅读器自身的特点——既需要实现消息传输(登陆、发送一页等),又需要实现文件传输(小说下载功能),我针对这两个不同的需求分别定义了发送协议。
#### 1.4.1 消息传输
由于 Socket API 只支持 byte 型数据传输,所以在发送时先要将各种数据类型转换为 byte 类型。Python 已经为我们提供了许多转换的函数,但是由于各个类型的转换函数不同,使用起来不太方便。因此我写了两个通用转换函数(在 protocol/data_conversion 文件夹下),负责各个类型与 byte 类型之间的相互转换,其首先识别原数据类型,之后再调用相应的函数进行转换,给下面的编程带来了方便。
对每条消息我共做了三层封装,第一层封装的作用是将各种类型的数据转化为 byte 类型,正如前文所述,为了做到统一的数据转换,传输时需要指明原始数据类型及转换后 byte 数据的长度。第一层封装后数据格式如下:
| Type of Data (1 Byte) | Length of Data (4 Bytes) | Data |
| --------------------- | ------------------------ | ---- |
第二层封装的作用是组合消息头与消息体。类似于 HTTP 协议,每条发送的消息都可以分为两个部分:消息种类(消息头)和消息内容(消息体)。为了方便识别消息头,我给每个种类的消息定义了一个“int”型编号(定义在 message_type.py 文件中),映射关系如下。发送消息时转换为数字,接收消息时再转换回消息类型。
```c++
class MessageType(enum.IntEnum):
"""里 面 规 定 了 各 个 信 息 类 型 对 应 的 标 号 以 及 处 理 指 令 对 应 的 标 号"""
# === Client Action 1-100
login = 1
register = 2
require_list = 3
download = 4
start_read = 5
require_page = 6
update_bookmark = 7
# === Server Action 101-200
login_successful = 101
register_successful = 102
book_list = 103
file_size = 104
send_page = 105
send_chapter = 106 # 发 送 章 节 列 表
page_num = 107
total_page = 108
# === Failure 201-300
login_failed = 201 # 登 陆 失 败
username_taken = 202 # 用 户 名 被 占 用
no_book = 203 # 查 无 此 书
```
经过第二层封装后消息的格式如下。注意,由于消息头的长度和类型固定,所以无需使用第一层封装,而消息体则已经经过第一层封装。
| Message Type (4 Byte) | Message Body |
| --------------------- | ------------ |
第三层封装为**加密封装**,将第二层输出的结果作为一个整体加密。根据 AES 加密的规则(见 2.1.3 节),除了加密后的数据外,发送方还需要告知接收方消息总长度、填充位数以及初始化向量(Initialization Vector,IV)。我们将这三个信息依次封装在消息头部,最后是经过 AES 加密的第二层封装数据:
| Length of Message (4 Bytes) | Length of Padding (1 Byte) | AES IV (16 Bytes) | Message |
| --------------------------- | -------------------------- | ----------------- | ------- |
由于消息格式的统一,所以在服务器和客户端可以采用相同的函数来接收所有类型的消息。服务器在开启之后便一直处于监听状态,运行着接收消息的函数。而客户端则在有需要的时候运行,接收想要接收的消息。
#### 1.4.1 文件传输
文件传输相比于普通的消息传输有其自身的特殊性:
- 小说文件(txt 格式)本身可以用二进制方式读取直接得到 byte 格式的信息,无需调用函数转化。
- 小说的传输本身有连续性。一本小说需要分多次传输,而每次传输的长度和格式都相同(最后一次长度不同)。
所以对于文件传输只需要一层加密封装即可,加密后的数据格式为:
| Length of Padding (1 Byte) | AES IV (16 Bytes) | One File’s Part |
| -------------------------- | ----------------- | ---------------- |
我们在发送的数据里并没有包含长度,那么客户端该如何进行接收和解密呢?其实这涉及到文件发送的整体流程。在发送时,首先通过消息发送文件的总大小,再循环发送文件内容,这里我们规定每次发送的大小为定值(最后一次发送剩余值);接收时则相应先接受文件大小,然后客户端自动算出每次应接受的文件的大小,循环接收。
#### 1.4.1 加密算法
加密是传输协议的重点。
我通过设计“secure_channel”类(文件 protocol/secure_tr ansmission/secure_channel.py 中定义)构建了一个数据传输的“安全通道”,上文所述的加密与解密、发送与接收其实都是定义在该类里的函数。
服务器持续运行,当一个新的客户端建立时,第一件要做的事便是与服务器建立安全通道。这个建立过程包括两步:(I)客户端与服务器交换密钥(II)二者分别计算出共同密钥。建立完成之后,客户端与服务器各自保存密钥,接下来所有的信息交换都将依赖该安全通道传输。
在加密协议方面我选择了比较流行的 AES 的 CBC 加密,这是一种加密后长度不变的算法,不过需要被加密信息的长度为 16 的整数倍(因此才需要前文中的填充位)。加密算法如图 1。可以看到,该算法无论是加密还是解密都需要初始化向量和密钥两个信息,密钥在建立安全通道时计算出,之后就不再变化,初始化向量则每条消息都不相同,作为加密消息的头部一起发送。
![](https://www.writebug.com/myres/static/uploads/2021/10/25/509119351cdb1218030e9b4730264f21.writebug)
图 1: AES 的 CBC 加密过程图
## 1.5 服务器
服务器端的内容存放在 server 文件夹中。根据设计思路,所有的小说都应存放在服务器端,我把它们放在 server/books 文件夹下。服务器代码最主要的功能就是不断监听从客户端发来的请求,然后针对该请求发送相应的回复。为了能让服务器同时支持多个客户端并长时间运行,我采用了多线程的设计,每当客户端发来一个信息时便给它分配一个线�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
小说阅读器使用 Python 编写,图形界面使用 Tkinter 库,信息传输依赖标准的 Socket API。提供的功能有:用户注册、用户登录、小说阅读、小说下载。对所有使用 Socket 传输的信息都实现了加密,保证信息安全。在服务器端采用多线程设计,可长时间运行并支持同时支持多个客户端。
资源推荐
资源详情
资源评论
收起资源包目录
100012865-基于Python实现的(GUI)小说阅读器.zip (50个子文件)
bookreader
run_server.py 34B
protocol
data_conversion
from_byte.py 3KB
to_byte.py 3KB
secure_transmission
secure_channel.py 9KB
cryptogram.py 1KB
utils
read_config.py 262B
__init__.py 497B
message_type.py 750B
run_client.py 34B
LICENSE 1KB
Picture
CBC_encryption.svg.png 8KB
CBC_decryption.svg.png 9KB
client
__init__.py 792B
forms
reader_form.py 16KB
bookshelf_form.py 4KB
register_form.py 3KB
login_form.py 3KB
memory.py 139B
摘要.md 7KB
实验报告.pdf 1.59MB
config.json 453B
.gitignore 1KB
server
__init__.py 4KB
memory.py 255B
books
Little Prince.txt 90KB
万历十五年.txt 496KB
老残游记.txt 321KB
users.txt 106B
event
send_page.py 645B
utils.py 1KB
__init__.py 662B
send_list.py 395B
start_read.py 2KB
register.py 867B
send_book.py 520B
login.py 805B
update_bookmark.py 1KB
img.doc-md
9-8fdc2d66eb6748764183df637673553e.png 252KB
11-ee037d8e9ad5c23a15809b0c5993b058.png 66KB
10-f478aa09be4c0caf3b01fa2670e8353a.png 313KB
3-b91d11c206543a43b4a343847b3b3107.png 62KB
12-e7662fa7d6d37b816386cf4eee6afbe1.png 44KB
1-997f0fb8e7b01cc3f38eeaa5ed1db983.png 134KB
4-22c1bd5bd03c8688e550f6645181f51a.png 30KB
5-434d33621ba7f0068f0f8db68f881dc4.png 18KB
7-7187ed900eba4a528f125bf97d643d9b.png 30KB
6-a5dcdf0abf9c80677c300255a5d9cb4c.png 34KB
2-6a8f917cfa43169bff21d9ae91cd3f6b.png 65KB
8-9d94e505c03096694599d86bb004ca9a.png 12KB
README.md 18KB
共 50 条
- 1
资源评论
神仙别闹
- 粉丝: 2679
- 资源: 7667
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功