tcp服务器多人聊天转发数据。
'''
描述:局域网内基于多线程的TCP socket 聊天室。
'''
import sys
from PyQt5.QtWidgets import QApplication,QLabel,QWidget,QVBoxLayout
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
import socket,threading,time
clients = {}
class client(object):
def __init__(self,socket,addr,username):
self.addr = addr[0]
self.port = addr[1]
self.username = username
self.socket=socket
def sendMsg(self,msg,username,admin):
try:
self.socket.send(("%s%s%s" % (self.getTime(), username, msg)).encode("utf-8"))
except:
return False
def recv(self,mtu=1024):
try:
data = self.socket.recv(mtu).decode("utf-8")
if data == "-!-quit-!-" or not data:
return False
return data
except:
return False
def close(self):
try:
self.socket.close()
return True
except:
return False
def getId(self):
return "%s-%s" % (self.addr,self.port)
def getTime(self):
return str(time.strftime(""))
def new_client(c):
try:
print("用户%s %s(%s)已连接" %(c.username,c.addr,c.port))
c.socket.send("已连接".encode("utf-8"))
while True:
data = c.recv()
if not data:
break
else:
print("用户%s %s(%s) 发送了: %s" % (c.username,c.addr, c.port, data))
broadcast(data,c.username)
finally:
print("%s(%s) 断开连接" % (c.addr, c.port))
c.close()
clients.pop(c.getId())
broadcast(data, c.username)
def broadcast(msg,username,admin=False):
for c in clients.values():
c.sendMsg(msg,username,admin)
def start_server(port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = "192.168.31.157"
server.bind((host, port))
# 监听客户端
server.listen(10)
print("服务器已开启,正在监听{}".format(server.getsockname()))
while True:
# 接受客户端连接
conn, addr = server.accept()
c = client(conn,addr,"")
clients[c.getId()] = c
t = threading.Thread(target=new_client, args=(c,))
t.start()
if __name__ == "__main__":
start_server(8089)
print("服务器已关闭")