import socket
import threading
import random
import math
import time
#对所有连接用户进行广播
def broadcast(message, freshMethod = None):
for peer in USER_LIST.values():
try:
peer.sendTo(message)
except:
#应该在系统内清除相应连接
peer.leave()
if freshMethod:
freshMethod(peer)
class user:
def __init__(self, nickName, currentChannel, userSocket, addr):
self.nickName = nickName
self.currentChannel = currentChannel
self.userSocket = userSocket
self.address = addr
def sendTo(self,message):
#向用户发送消息数据
self.userSocket.send(message)
def leave(self):
self.userSocket.shutdown(2)
self.userSocket.close()
class channel:
def __init__(self, channelName, user, userName, admin):
self.channelName = channelName
self.users = user
self.userNames = userName
self.admin = admin
def addNewUser(self, user, userName): #此处的user为用户的对象
self.users.append(user)
self.userNames.append(userName)
def removeUser(self, user, userName):
self.users.remove(user)
self.userNames.remove(userName)
def chat(self,message,freshMetohd = None):
for peer in self.users:
try:
peer.sendTo(message)
except:
print(peer.nickName +'::' + str(peer.address) + 'could not be connected.\n')
peer.leave()
if freshMetohd:
freshMetohd(peer)
self.removeUser(peer,peer.nickName)
def getList(self):
message = 'LIST {}'.format(str(self.userNames))
return message
def listFresh(userObj): #此处传入参数为user类
addr = userObj.address
nickName = userObj.nickName
del USER_LIST[addr]
del NICK_NAME[nickName]
def clearSock(User):
if User.currentChannel:
CHANNEL_LIST[User.currentChannel].removeUser(User,User.nickName)
User.leave()
addr = User.address
nickName = User.nickName
del USER_LIST[addr]
if nickName:
del NICK_NAME[nickName]
def clientHandel(User):
conn = User.userSocket
while True:
try:
recvData = conn.recv(RECV_BUFFER_LENGTH)
except:
print('Connect form {} has been shutdown.'.format(User.address))
clearSock(User)
print('Connect form {} has been cleared.'.format(User.address))
break
else:
#处理client死链接的情况
recvData = recvData.decode('utf-8')
if recvData == '':
print('Connect form {} has been shutdown.'.format(User.address))
clearSock(User)
print('Connect form {} has been cleared.'.format(User.address))
break
recvData = eval(recvData)
recvData = RSADecrypt(RSA_keyD, RSA_n, recvData)
temp_data = recvData.split()
if temp_data[0] == 'NICK':
try:
nickName = temp_data[temp_data.index('NICK')+1]
except:
info = 'SERVER(000)::Syntex Error *please specify a nick name.\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
conn.send(info)
else:
if nickName in NICK_NAME.keys():
print('User from:'+str(addr)+'--set nick name unsuccessfully!')
print('@'+nickName+'already in the server!')
info = 'SERVER(433)::Name had already been token,please try another!\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
conn.send(info)
else:
print('User from:'+str(addr)+'--set nick name successfully!')
print('@'+nickName+'')
info = 'SERVER(376)::Welcome!\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
conn.send(info)
NICK_NAME[nickName] = addr
User.nickName = nickName
if temp_data[0] == 'JOIN':
try:
channelName = temp_data[temp_data.index('JOIN')+1]
except:
print('*{}*try to join a channel with a wrong Syntex.'.format(User.nickName))
print('----Didn\'t specified a channel name----')
info = 'SERVER(000)::Syntex Error *please specify a channel.\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
conn.send(info)
else:
if channelName[0] == '#':
if channelName in CHANNEL_LIST.keys():
CHANNEL_LIST[channelName].addNewUser(User,nickName)
print('<{}> entered channel <{}>'.format(User.nickName, channelName))
info = 'SERVER(366)::Join successd!\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
conn.send(info)
time.sleep(10/(10^6))
# #通知房间所有人
# info = '<{}> entered the channel\n'.format(User.nickName)
# info = RSAEncrypt(RSA_keyD, RSA_n, info)
# info = str(info).encode('utf-8')
# CHANNEL_LIST[channelName].chat(info, listFresh)
# time.sleep(10/(10^6))
#更新用户列表数据
channleUser = CHANNEL_LIST[channelName].getList()
channleUser = RSAEncrypt(RSA_keyD, RSA_n, channleUser)
channleUser = str(channleUser).encode('utf-8')
CHANNEL_LIST[channelName].chat(channleUser, listFresh)
else:
newChannel = channel(channelName, [User], [User.nickName], User)
CHANNEL_LIST[channelName] = newChannel
print('<{}> started a new channel <{}>'.format(User.nickName, channelName))
info = 'SERVER(367)::New channel set!\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
info = str(info).encode('utf-8')
CHANNEL_LIST[channelName].chat(info, listFresh)
channleUser = CHANNEL_LIST[channelName].getList()
channleUser = RSAEncrypt(RSA_keyD, RSA_n, channleUser)
channleUser = str(channleUser).encode('utf-8')
CHANNEL_LIST[channelName].chat(channleUser, listFresh)
#设置用户当前channel
USER_LIST[addr].currentChannel = channelName
else:
print('*{}*try to join a channel with a wrong Syntex.'.format(User.nickName))
print('----Channel name without "#"----')
info = 'SERVER(000)::Syntex Error channel name must start with a "#".\n'
info = RSAEncrypt(RSA_keyD, RSA_n, info)
没有合适的资源?快使用搜索试试~ 我知道了~
Python+PyQt 5+RSA非对称加密实现基于IRC协议的多人聊天系统(含服务端和客户端源码)
共6个文件
png:4个
py:2个
4星 · 超过85%的资源 需积分: 50 35 下载量 100 浏览量
2020-04-14
10:49:06
上传
评论 7
收藏 216KB ZIP 举报
温馨提示
用 Python 实现协议的多人聊天系统,现仅支持局域网环境下使用。 用户端:采用 PyQt 5 进行设计;主要有登录窗口和聊天窗口;通过用户名对用户进行区分;支持用户登录信息保存;支持常用IRC命令;支持当前在线用户列表显示。 服务端:实时用户管理;每个用户独立线程工作;负责 RSA 密钥的分发与更新。 【说明】运行 server.py 可获取 HOST(主机地址)和 PORT(端口号),运行 client.py 后输入对应服务器地址和端口号方可成功登录。Bug 还是有的,因为这个做的比较着急,是课程设计用的,请大家见谅。
资源推荐
资源详情
资源评论
收起资源包目录
IRC_Chat.zip (6个子文件)
client_v3.1.py 17KB
pic
北京森林工作室.png 11KB
校徽.png 189KB
exit.png 213B
Chat.png 5KB
server.py 21KB
共 6 条
- 1
资源评论
- 潜水ing今天不潜水2021-06-01有用!!!!!!!
JoshGao
- 粉丝: 400
- 资源: 98
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功