(资料图片)
目录
1.socket_ui.py 服务端1-1. 依赖引用1-2. 实现过程1-3. 实现效果2.client_ui.py 客户端2-1. 依赖引用2-2. 实现过程2-3. 实现效果在这个周末刚刚写出来的python桌面应用--网络聊天室,主要通过pyqt5作为桌面应用框架,socket作为网络编程的框架,从而实现包括客户端和服务端的网络聊天室的GUI应用,希望可以一起学习、一起进步!
应用包括服务端server_ui.py、客户端client_ui.py两个python模块实现,并且在pyqt5的使用过程中都使用QThread多线程应用以及基本的UI页面布局。开始之前通过一个动态图来观察一下socket服务端、socket客户端通信的实现效果。
1.socket_ui.py 服务端
1-1. 依赖引用
在socket服务端的实现过程中,除了pyqt5相关的UI界面的引用外,还包括time、threading、sys、socket等辅助模块来一起实现socket服务端的桌面应用程序。
from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import sys from QCandyUi import CandyWindow # 导入 socket 通讯模块 import socket # 导入时间管理模块 import time # 导入多线程模块 import threading
1-2. 实现过程
在服务端的业务实现上面,我们依然是按照之前的GUI实现方式,采用主线程用来实现页面布局,子线程QThread来实现业务逻辑的方式来进行实现的,socket的服务端通信业务都是在子线程ServerThread中编写的。下面是socket服务端桌面应用实现的全部代码块,copy到自己的ide中即可直接启动使用。
class ServerUI(QWidget): def __init__(self): super(ServerUI, self).__init__() self.init_ui() def init_ui(self): self.setWindowTitle("socket 服务端 公众号:[Python 集中营]") self.setWindowIcon(QIcon("hi.ico")) self.setFixedSize(500, 300) hbox = QHBoxLayout() hbox_v1 = QVBoxLayout() self.brower = QTextBrowser() self.brower.setFont(QFont("宋体", 8)) self.brower.setReadOnly(True) self.brower.setPlaceholderText("消息展示区域...") self.brower.ensureCursorVisible() hbox_v1.addWidget(self.brower) hbox_v2 = QVBoxLayout() hbox_v2_f1 = QFormLayout() self.ip_label = QLabel() self.ip_label.setText("ip地址 ") self.ip_txt = QLineEdit() self.ip_txt.setPlaceholderText("0.0.0.0") self.port_label = QLabel() self.port_label.setText("端口 ") self.port_txt = QLineEdit() self.port_txt.setPlaceholderText("4444") self.lis_num_label = QLabel() self.lis_num_label.setText("最大监听个数 ") self.lis_num_txt = QLineEdit() self.lis_num_txt.setPlaceholderText("10") self.close_cli_label = QLabel() self.close_cli_label.setText("客户端关闭指令 ") self.close_cli_txt = QLineEdit() self.close_cli_txt.setPlaceholderText("exit,客户端发送相应指令则关闭") hbox_v2_f1.addRow(self.ip_label, self.ip_txt) hbox_v2_f1.addRow(self.port_label, self.port_txt) hbox_v2_f1.addRow(self.lis_num_label, self.lis_num_txt) hbox_v2_f1.addRow(self.close_cli_label, self.close_cli_txt) self.start_btn = QPushButton() self.start_btn.setText("开启服务端") self.start_btn.clicked.connect(self.start_btn_clk) hbox_v2.addLayout(hbox_v2_f1) hbox_v2.addWidget(self.start_btn) hbox.addLayout(hbox_v1) hbox.addLayout(hbox_v2) self.thread_ = ServerThread(self) self.thread_.message.connect(self.show_message) self.setLayout(hbox) def show_message(self, text): """ 槽函数:向文本浏览器中写入内容 :param text: :return: """ cursor = self.brower.textCursor() cursor.movePosition(QTextCursor.End) self.brower.append(text) self.brower.setTextCursor(cursor) self.brower.ensureCursorVisible() def start_btn_clk(self): self.thread_.start() self.start_btn.setEnabled(False) class ServerThread(QThread): message = pyqtSignal(str) def __init__(self, parent=None): super(ServerThread, self).__init__(parent) self.parent = parent self.working = True def __del__(self): self.working = False self.wait() def run(self): self.message.emit("准备启动socket服务端...") # 创建服务端 socket socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定服务地址、端口 address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip())) socket_server.bind(address) # 设置监听最大等待数 socket_server.listen(int(self.parent.lis_num_txt.text().strip())) self.message.emit("服务已经启动,正在等待客户端连接...") while True: # 设置睡眠时间 time.sleep(0.1) # 允许客户端连接 client, info = socket_server.accept() self.client, self.info = client, info # 启用新线程调用消息处理 thread = threading.Thread(target=self.catch_message) # 设置为守护线程 thread.setDaemon(True) # 开启线程执行 thread.start() def catch_message(self): self.client.send("欢迎来到网络聊天室".encode("utf-8")) self.message.emit("客户端信息:" + str(self.info)) close_cli = self.parent.close_cli_txt.text().strip() while True: try: # 接收客户端消息、接收最大长度为 1024,并进行 utf-8 解码 message = self.client.recv(1024).decode("utf-8") # 校验是否关闭客户端 if not message and close_cli == message: self.client.close() self.message.emit("当前客户端已关闭!") break self.message.emit("接收到消息:" + message) # 将消息进行 utf-8 编码后发给客户端 rcv = "服务端成功接收消息:" + message self.client.send(rcv.encode("utf-8")) except Exception as e: self.client.send("服务端处理消息异常!".encode("utf-8")) break if __name__ == "__main__": app = QApplication(sys.argv) w = CandyWindow.createWindow(ServerUI(), theme="blueGreen", title="socket 服务端 公众号:[Python 集中营]", ico_path="hi.ico") w.show() sys.exit(app.exec_())
1-3. 实现效果
2.client_ui.py 客户端
2-1. 依赖引用
在socket客户端的实现过程中,除了pyqt5相关的UI界面的引用外,还包括sys、socket等辅助模块来一起实现socket服务端的桌面应用程序,相比服务端来说,客户端并没有使用多线程threading模块。
from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import sys from QCandyUi import CandyWindow # 导入socket 通信模块 import socket
2-2. 实现过程
客户端的实现过程和服务端server_ui.py实现是基本相似的,同样也使用到了pyqt5的QThread的子线程应用,唯一不同的是socket客户端通信方式跟服务端不大相同,同样将下面的代码块copy到自己的ide中直接使用即可。
class ClientUI(QWidget): def __init__(self): super(ClientUI, self).__init__() self.init_ui() def init_ui(self): self.setWindowTitle("socket 客户端 公众号:[Python 集中营]") self.setWindowIcon(QIcon("hi.ico")) self.setFixedSize(500, 300) hbox = QHBoxLayout() hbox_v1 = QVBoxLayout() self.brower = QTextBrowser() self.brower.setFont(QFont("宋体", 8)) self.brower.setReadOnly(True) self.brower.setPlaceholderText("消息展示区域...") self.brower.ensureCursorVisible() hbox_v1.addWidget(self.brower) hbox_v2 = QVBoxLayout() hbox_v2_g1 = QGridLayout() self.ip_label = QLabel() self.ip_label.setText("ip地址 ") self.ip_txt = QLineEdit() self.ip_txt.setPlaceholderText("0.0.0.0") self.port_label = QLabel() self.port_label.setText("端口 ") self.port_txt = QLineEdit() self.port_txt.setPlaceholderText("4444") self.message = QTextEdit() self.message.setPlaceholderText("发送消息内容...") hbox_v2_g1.addWidget(self.ip_label, 0, 0, 1, 1) hbox_v2_g1.addWidget(self.ip_txt, 0, 1, 1, 1) hbox_v2_g1.addWidget(self.port_label, 1, 0, 1, 1) hbox_v2_g1.addWidget(self.port_txt, 1, 1, 1, 1) hbox_v2_g1.addWidget(self.message, 2, 0, 1, 2) self.start_btn = QPushButton() self.start_btn.setText("发送消息") self.start_btn.clicked.connect(self.start_btn_clk) hbox_v2.addLayout(hbox_v2_g1) hbox_v2.addWidget(self.start_btn) hbox.addLayout(hbox_v1) hbox.addLayout(hbox_v2) self.thread_ = ClientThread(self) self.thread_.message.connect(self.show_message) self.setLayout(hbox) def show_message(self, text): """ 槽函数:向文本浏览器中写入内容 :param text: :return: """ cursor = self.brower.textCursor() cursor.movePosition(QTextCursor.End) self.brower.append(text) self.brower.setTextCursor(cursor) self.brower.ensureCursorVisible() def start_btn_clk(self): self.thread_.start() class ClientThread(QThread): message = pyqtSignal(str) def __init__(self, parent=None): super(ClientThread, self).__init__(parent) self.parent = parent self.working = True self.is_connect = False def __del__(self): self.working = False self.wait() def run(self): try: if self.is_connect is False: self.connect_serv() # 将控制台输入消息进行 utf-8 编码后发送 self.socket_client.send(self.parent.message.toPlainText().strip().encode("utf-8")) self.message.emit(self.socket_client.recv(1024).decode("utf-8")) except Exception as e: self.message.emit("发送消息异常:" + str(e)) def connect_serv(self): try: self.message.emit("正在创建客户端socket...") # 创建客户端 socket self.socket_client = socket.socket() # 连接服务端 address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip())) self.socket_client.connect(address) self.message.emit("服务端连接成功...") # 接收服务端消息并进行 utf-8 解码 self.message.emit(self.socket_client.recv(1024).decode()) self.is_connect = True except: self.is_connect = False if __name__ == "__main__": app = QApplication(sys.argv) w = CandyWindow.createWindow(ClientUI(), theme="blueGreen", title="socket 客户端 公众号:[Python 集中营]", ico_path="hi.ico") w.show() sys.exit(app.exec_())
2-3. 实现效果
以上就是基于Python socket实现简易网络聊天室的详细内容,更多关于Python socket网络聊天室的资料请关注脚本之家其它相关文章!
X 关闭
X 关闭
- 1充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 2好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 3名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 4亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 5京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 6网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 7市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 8北京市市场监管局为企业纾困减负保护经济韧性
- 9市场监管总局发布限制商品过度包装标准和第1号修改单
- 10油价又变了!部分地区92号汽油进入“9元时代”