PyQt5+socket+多线程,实现简单聊天室( 三 )


服务器服务端代码,这个主要是我用在腾讯云服务器上的代码 , 因为服务器没有界面,就省去了界面制作 。!!在上运行的如果写了中文得表明为gbk编码,否则会报错 。其次这里主要使用的是(一个和PyQt5基本一样的模块),因为PyQt5在上安装半天都失败 。
# -*- coding:gbk -*-#!/usr/bin/python3from PySide2.QtWidgets import QApplicationfrom PySide2.QtCore import QThread,Signalimport socketimport sysclass Server():def __init__(self,ip,host,port):self.ip = ipself.hostName = hostself.port = portself.serverDict = {}self.serverID = 0self.buildSocket()def buildSocket(self):self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.initialServer()def initialServer(self):self.socket.bind((self.ip,self.port))self.socket.listen(5)print("start create serverThread")self.buildServer()def buildServer(self):server = ServerThread(str(self.serverID),self.socket)print("Thread server Created!")self.serverDict[str(self.serverID)] = serverself.serverID+=1server._flag.connect(self.getFlag)server._signal.connect(self.getMessage)server._text.connect(self.getText)server.start()print("Server create successfully!")def bordCastInfo(self,info):for client in self.serverDict:try:if self.serverDict[client].clientsocket != None:print("try boardcasting")self.serverDict[client].sendToClient(info)print("boardcast success")except Exception as reason:self.getFlag("@@@".join([client,"disconnect"]))print("Server:",reason)def btnsend(self,text):self.widget.chatEdit.append(text)self.bordCastInfo(text)def closeThread(self):for server in self.serverDict:self.serverDict[server].runflag = Falsedef getFlag(self,flag):flag = flag.split("@@@")if flag[1] == "connect":self.buildServer()elif flag[1] == "disconnect":self.serverDict[flag[0]].runflag = Falsedef getMessage(self,signal):signal = signal.split("@@@")print("serverID "+signal[0]+" status:"+signal[1])def getText(self,text):print(text)self.bordCastInfo(text)class ServerThread(QThread):_signal = Signal(str)_text = Signal(str)_flag = Signal(str)def __init__(self,serverID,serverSocket):super(ServerThread, self).__init__()self.serverID = serverIDself.serverSocket = serverSocketself.clientsocket = Noneself.addr = Noneself.runflag = Trueself.connectList = ["connect","disconnect"]def run(self):print("Waiting for customer......")self.clientsocket,self.addr = self.serverSocket.accept()print("Customer IP: %s" % str(self.addr)+" is linking!")self.sendFlag(0)self.getMessage()def getMessage(self):while self.runflag:try:data = http://www.kingceram.com/post/self.clientsocket.recv(1024).decode('utf-8')self.sendText(data)except Exception as reason:self.sendMessage(str(reason))self.sendText(str(self.addr)+" break connect...")self.sendFlag(1)breakself.clientsocket.close()print("Thread close successfully")def sendToClient(self,info):try:self.clientsocket.send(info.encode("utf-8"))print("boardcast success")except Exception as reason:print("boardcast failed:",reason)self.sendMessage(self.addr+" break connect...")self.sendFlag(1)def sendMessage(self,message):self._signal.emit("@@@".join([self.serverID,message]))def sendText(self,text):self._text.emit(text)def sendFlag(self,flagIndex):self._flag.emit("@@@".join([self.serverID,self.connectList[flagIndex]]))if __name__ == "__main__":app = QApplication(sys.argv)print("Here is Server! - input 'Server' to Create a Server")print("localhost IP: 82.157.140.78")ip = "0.0.0.0"hostName = "Server"port = 9995server = Server(ip,hostName,port)app.exec_()
6.大坑提醒
(1) 要想使用的TCP协议通过指定端口连接服务器得在服务器安全设置中开启指定端口才行 , 不然你怎么都连接不上
(2) 校园网对于网络专业来说就是个大坑  , 通常学校为了保证网络安全会做内网隔断,即内网内的主机之间不能相互通信 , 如果你ping不通对方主机ip就尝试用手机流量开热点吧...
(3) 上第一次运行PyQt5或可能会丢出"Thisto startno Qtcould be "之类的错误 , 主要原因就是环境没配好(配了我一个下午T_T),看这篇文章可能会解决你的问题>>>解决方案