1.服务器端代码
import socket
from threading import Thread
import time
class ServerChat:
def __init__(self):
self.server = socket.socket()
self.server.bind(('localhost', 9999))
self.server.listen(5)
# 所有客户端的socket
self.clients = []
# 所有客户端的名字
self.clients_name_ip = {}
# 监听客户端连接
def get_conn(self):
while True:
# 获取客户端连接
client, address = self.server.accept()
self.clients.append(client)
print('连接地址:', address)
data = "欢迎来到聊天室,请输入你的名字:"
client.send(data.encode('utf-8'))
# 创建一个线程,监听客户端消息
thread = Thread(target=self.get_msg, args=(client, self.clients, self.clients_name_ip, address))
thread.start()
# 监听客户端消息
def get_msg(self, client, clients, client_name_ip, address):
# 获取客户端的名字
name = client.recv(1024).decode('utf-8')
print(name + "加入聊天室")
# 将客户端的名字和ip地址保存到字典中
client_name_ip[address] = name
data = "欢迎%s来到聊天室" % name
client.send(data.encode('utf-8'))
while True:
try:
recv_data = client.recv(1024).decode('utf-8')
print("接收到来自%s的消息:%s" % (name, recv_data))
except Exception as e:
print(e)
break
# 如果用户退出,则输入“Q”
if recv_data.upper() == 'Q':
self.close_client(client, address)
break
for c in clients:
c.send((client_name_ip[address] + " " + time.strftime("%X") + "\n" + recv_data).encode('utf-8'))
# 关闭客户端连接
def close_client(self, client, address):
self.clients.remove(client)
client.close()
print(self.clients_name_ip[address] + "退出聊天室")
for c in self.clients:
c.send((self.clients_name_ip[address] + "退出聊天室").encode('utf-8'))
if __name__ == '__main__':
server = ServerChat()
server.get_conn()
2.客户端代码
from PyQt5 import QtGui
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import *
import sys
import socket
from threading import Thread
class Client(QWidget):
def __init__(self):
QWidget.__init__(self)
# 设置窗口的大小和位置
self.send = None
self.message = None
self.content = None
self.setGeometry(600, 300, 360, 300)
# 设置标题
self.setWindowTitle('聊天室')
# 添加背景
palette = QtGui.QPalette()
bg = QtGui.QPixmap('background.png')
palette.setBrush(self.backgroundRole(), QtGui.QBrush(bg))
self.setPalette(palette)
self.add_ui()
# 与服务器建立连接
self.client = socket.socket()
self.client.connect(('localhost', 9999))
self.work_thread()
# 设置界面中的组件
def add_ui(self):
# 多行文本框,显示聊天记录
self.content = QTextBrowser(self)
self.content.setGeometry(30, 30, 300, 150)
# 单行文本框,消息发送框
self.message = QLineEdit(self)
self.message.setPlaceholderText("请输入消息")
self.message.setGeometry(30, 200, 300, 30)
# 发送按钮
self.send = QPushButton('发送', self)
self.send.setFont(QFont("宋体", 10, QFont.Bold))
self.send.setGeometry(30, 240, 300, 30)
self.send.clicked.connect(self.send_msg)
def send_msg(self):
# 获取文本框的内容
msg = self.message.text()
# 发送消息
self.client.send(msg.encode('utf-8'))
print("发送消息:", msg)
if msg.upper() == 'Q':
self.close()
self.destroy()
# 清空消息发送框
self.message.clear()
def recv_msg(self):
while True:
try:
recv_data = self.client.recv(1024).decode('utf-8')
print(recv_data)
recv_data = recv_data + '\n'
self.content.append(recv_data)
except Exception as e:
print(e)
break
def work_thread(self):
Thread(target=self.recv_msg).start()
if __name__ == '__main__':
app = QApplication(sys.argv)
client = Client()
client.show()
sys.exit(app.exec_())
在Pycharm中先运行服务器,在运行客户端,即可使用