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)