# 功能
- [x] Diffie-Hellman 密钥交换安全传输(启动时第一件事)
- [x] 用AES加密所有的传输内容
- [x] 包分为OpCode和Parameters,用binary序列化反序列化Parameters
- [x] 使用数据库存储用户信息、好友关系、房间信息、加入房间状态、所有聊天记录
- [x] tkinter GUI
- [x] 有新消息时自动滚动到底部
- [x] 窗口放大缩小
- [x] 服务器、客户端通过JSON文件配置
- [x] 联系人列表;按照最后发消息的时间排序好友和群;未读的消息用红点标注数量;显示并实时更新在线状态
- [x] 加好友功能,对方收到通知,通过/拒绝/推迟到下次登入时询问
- [x] 防止重复打开窗口,如果已经打开则使窗口获得焦点
- [x] 账号只能在一处登入,在别处登入时把原来登入的踢下线
- [x] 再次打开时恢复所有聊天记录、用户离线时收到的未读的消息用红点标注数量
- [x] 支持多行内容(Enter换行,Ctrl+Enter发送);支持聊天字体的设置
- [x] 支持图片传输
- [x] 群聊功能、加群、创建群
- [x] 群聊中显示群成员(双击打开聊天窗口/发送好友请求);实时显示群成员在线状态,置顶在线的成员
- [x] 智能的联系人列表中的最近消息(同QQ,群聊则显示发送者昵称,图片则显示[图片消息],自动处理换行)
# 安装说明
Python版本: 3.5
```
pip install pycrypto # 用于AES加密
pip install Pillow # 支持JPG等格式图片的发送
```
也可以运行
```
pip install -r requirements.txt
```
# 运行方法
```
python run_client.py
python run_server.py
```
(一次只能运行一个server,但可以运行N个client)
# 配置文件
server和client共用```config.json```
```
{
"crypto": {
"base": ..,
"modulus": ...
},
"client": {
"server_ip": "127.0.0.1",
"server_port": 8111
},
"server": {
"bind_ip": "0.0.0.0",
"bind_port": 8111
}
}
```
大多都容易理解,需要注意的是```crypto```部分,这里的```base```和```modulus```是Diffie-Hellman密钥交换时用到的,应该为两个大素数。
# 文件目录
```
│ config.json
│ README.md
│ run_client.py
│ run_server.py
│
├─client
│ │ __init__.py
│ │
│ ├─components
│ │ contact_item.py
│ │ vertical_scrolled_frame.py
│ │ __init__.py
│ │
│ ├─forms
│ │ boilerplate.txt
│ │ chat_form.py
│ │ contacts_form.py
│ │ login_form.py
│ │ register_form.py
│ │ __init__.py
│ │
│ ├─memory
│ │ __init__.py
│ │
│ └─util
│ │ __init__.py
│ │
│ └─socket_listener
│ __init__.py
│
├─common
│ │ config.py
│ │ global_vars.py
│ │ __init__.py
│ │
│ ├─cryptography
│ │ crypt.py
│ │ prime.py
│ │ __init__.py
│ │
│ ├─message
│ │ __init__.py
│ │
│ ├─transmission
│ │ secure_channel.py
│ │ __init__.py
│ │
│ └─util
│ __init__.py
│
└─server
│ database.db
│ main.sql
│ __init__.py
│
├─broadcast
│ __init__.py
│
├─event_handler
│ add_friend.py
│ client_echo.py
│ create_room.py
│ join_room.py
│ login.py
│ query_room_users.py
│ register.py
│ resolve_friend_request.py
│ send_message.py
│ __init__.py
│
├─memory
│ __init__.py
│
└─util
│ __init__.py
│
└─database
__init__.py
```
# 预览图
![1](preview_imgs/1.png)
![2](preview_imgs/2.png)
![3](preview_imgs/3.png)
![4](preview_imgs/4.png)
![5](preview_imgs/5.png)
![6](preview_imgs/6.png)
![7](preview_imgs/7.png)
![8](preview_imgs/8.png)
# 自制聊天协议说明
本聊天协议受到HTTP协议启发
1. 无状态(除了登入操作之外)。
2. Request Body和Response Body使用键值对的方式,键为string,值可以为任意类型。
略作了修改
1. 登入时设置socket状态,后续传输不必再次说明身份。
2. 每个包头加入Request/Response Type,每个Type对应一种固定的操作,对应固定的参数列表。
3. 使用二进制而非类JSON方式传输,节省流量。
这种设计的优点
1. 简单易懂,易于测试(因为无状态)。
2. 灵活方便,无需为不同的操作类型写不同的处理程序。
3. 可以传输非常复杂的数据结构(如:登入时的所有N条未读消息(每条都含有发件人/时间/消息内容/甚至图片二进制)都是放在一个包里的)。
这种设计的缺点
1. 每个字段要指定一个key(如:user,pwd),每个value的类型要有一个byte指定,略浪费流量。
增加安全性,防止被窃听:
1. 自制的安全传输协议,在启动时会使用Diffie-Hellman算法与服务器交换密钥。
2. 交换完密钥后,所有的传输都会经过AES加密。
3. 客户端和服务器除了在协议上需要达到共识,不需要共享任何其他数据。
4. 在不安全的信道上,就算所有数据都被窃听,窃听者也无法解密消息内容。
缺点:
1. 无法防中间人攻击(没有做数字签名等)。
![8](preview_imgs/dfh.png)
# 协议详细说明
*注:具体实现可以看```src/common/cryptography```、```src/common/transmission```和```src/common/message```*
协议设计的宗旨是:无状态、分层设计、以先发送长度再发送内容的方式设计。
网络包分为四层,前三层格式一致,第四层是值层,格式根据值类型不同而不同。构造分别如下:
## 层1(解密前):
1. Length of Message Body (4Bytes)
2. Length of AES padding (1Byte) *AES加密填充用*
3. AES IV (16Bytes) *AES初始向量*
4. Message Body *被AES加密的内容*
## 层2(解密后):
1. Message Type (4Bytes) *定义```MessageType```,见```src/common/message```*
2. Array of parameters.. *N个层3的数据*
## 层3(参数):
1. Type of Parameter (1Byte) *定义```VAR_TYPE```,见```src/common/message```*
2. Length of Body (4 Bytes)
3. Body of Parameter *具体层4的数据,怎么解释需要根据```VAR_TYPE```决定,见层4*
## 层4(基础类型如int、str、bool、float、binary等):
1. Packed Data (Using struct.pack in Python) *(直接转成bytes)*
## 层4(List):
1. Array of Level 3 Data Pack *(N个层3的数据)*
## 层4(Dictionary):
1. Length of Key (1 Byte) *Key的长度*
2. Key *Key的值(字符串)*
3. Level 3 Data Pack *层3数据作为Value的值*
4. Repeat.. *重复123*
一般来说,真正使用时,会选择直接发送一个List或者Dictionary作为层3,这样可以一次和服务器交换多个参数。
比如```self.sc.send(MessageType.login, [username, password])```
这种设计非常强大,结合```src/common/transmission```中的AES加密,可以无缝和服务器**安全**交换非常复杂的数据。比如,一个用户的所有离线未读消息(有N条,每条可能是不同的房间、不用的发送者,都包含不同的时间、字体大小,可能还有图片),可以通过一个包发送给客户端,效率非常高。
# 用SQLite存储用户信息和未读消息
数据库在```src/server/database.db```,结构如下:
```
CREATE TABLE "chat_history" (
"id" INTEGER NOT NULL,
"user_id" INTEGER,
"target_id" INTEGER,
"target_type" TEXT,
"data" BLOB,
"sent" INTEGER,
PRIMARY KEY ("id" ASC)
);
CREATE TABLE "friends" (
"from_user_id" INTEGER NOT NULL,
"to_user_id" INTEGER NOT NULL,
"accepted" TEXT,
PRIMARY KEY ("from_user_id" ASC, "to_user_id")
);
CREATE TABLE "rooms" (
"id" INTEGER NOT NULL,
"room_name" TEXT,
PRIMARY KEY ("id")
);
CREATE TABLE "room_user" (
"id" INTEGER
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
功能 Diffie-Hellman 密钥交换安全传输(启动时第一件事) 用AES加密所有的传输内容 包分为OpCode和Parameters,用binary序列化反序列化Parameters 使用数据库存储用户信息、好友关系、房间信息、加入房间状态、所有聊天记录 tkinter GUI 有新消息时自动滚动到底部 窗口放大缩小 服务器、客户端通过JSON文件配置 联系人列表;按照最后发消息的时间排序好友和群;未读的消息用红点标注数量;显示并实时更新在线状态 加好友功能,对方收到通知,通过/拒绝/推迟到下次登入时询问 防止重复打开窗口,如果已经打开则使窗口获得焦点 账号只能在一处登入,在别处登入时把原来登入的踢下线 再次打开时恢复所有聊天记录、用户离线时收到的未读的消息用红点标注数量 支持多行内容(Enter换行,Ctrl+Enter发送);支持聊天字体的设置 支持图片传输 群聊功能、加群、创建群 群聊中显示群成员(双击打开聊天窗口/发送好友请求);实时显示群成员在线状态,置顶在线的成员 智能的联系人列表中的最近消息(同QQ,群聊则显示发送者昵称
资源推荐
资源详情
资源评论
收起资源包目录
network-pj-chatroom.zip (83个子文件)
network-pj-chatroom
run_server.py 26B
preview_imgs
3.png 26KB
dfh.png 44KB
1.png 7KB
6.png 25KB
5.png 82KB
4.png 23KB
8.png 335KB
7.png 38KB
2.png 127KB
run_client.py 26B
presentation_slides.pptx 823KB
client
__init__.py 779B
forms
__init__.py 1B
boilerplate.txt 2KB
contacts_form.py 9KB
register_form.py 3KB
chat_form.py 9KB
login_form.py 3KB
components
__init__.py 1B
vertical_scrolled_frame.py 2KB
contact_item.py 2KB
memory
__init__.py 530B
util
__init__.py 0B
socket_listener
__init__.py 5KB
.git
index 6KB
HEAD 23B
refs
heads
master 41B
tags
remotes
origin
HEAD 32B
objects
pack
pack-e04b6a670d8aa79b858b415af220765714f9332d.pack 2.4MB
pack-e04b6a670d8aa79b858b415af220765714f9332d.idx 11KB
info
description 73B
packed-refs 114B
info
exclude 240B
logs
HEAD 191B
refs
heads
master 191B
remotes
origin
HEAD 191B
hooks
post-update.sample 189B
prepare-commit-msg.sample 1KB
commit-msg.sample 896B
pre-receive.sample 544B
update.sample 4KB
pre-commit.sample 2KB
pre-rebase.sample 5KB
applypatch-msg.sample 478B
fsmonitor-watchman.sample 5KB
push-to-checkout.sample 3KB
pre-applypatch.sample 424B
pre-push.sample 1KB
pre-merge-commit.sample 416B
config 344B
common
__init__.py 0B
message
__init__.py 6KB
global_vars.py 28B
cryptography
__init__.py 1B
crypt.py 448B
prime.py 462B
util
__init__.py 1KB
transmission
__init__.py 1B
secure_channel.py 4KB
config.py 154B
requirements.txt 29B
config.json 451B
.gitignore 23B
server
__init__.py 4KB
database.db 7KB
main.sql 2KB
broadcast
__init__.py 132B
memory
__init__.py 439B
util
__init__.py 70B
database
__init__.py 4KB
event_handler
client_echo.py 304B
__init__.py 1003B
bad.py 227B
create_room.py 625B
query_room_users.py 527B
resolve_friend_request.py 1KB
register.py 708B
add_friend.py 1KB
send_message.py 3KB
login.py 2KB
join_room.py 675B
README.md 10KB
共 83 条
- 1
资源评论
进击的代码家
- 粉丝: 2747
- 资源: 204
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功