小編寫這篇文章的主要目的,主要介紹的是關于Python socket的相關知識,介紹的內容主要是涉及到編程的一些事情,以此用來進行搭建簡易的網絡聊天室,來實現相關的遠程聊天,這其實就是聊天工具的初始原型,下面就具體的內容給大家詳細解答下。
在這個周末剛剛寫出來的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客戶端
在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_())
綜上所述,這篇文章就給大家介紹完畢,希望可以給大家帶來幫助。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/128396.html
摘要:簡易版聊天室技術棧功能實現實時聊天創建房間表情包完善私聊效果登錄服務端判斷之前是否登錄過聊天室,如果是則直接進入聊天室,否則跳轉到登錄頁面。客戶端發送創建房間和切換房間的事件給服務端。 Chat 簡易版聊天室 技術棧 express socket.io 功能 實現 實時聊天 創建房間 表情包 完善 私聊 效果 登錄 showImg(https://segmentfa...
摘要:用偽代碼來模擬下長輪詢的過程前端利用下面函數進行請求后端代碼做如下更改利用隨機數的大小來模擬是否有新數據有新數據來了長輪詢的確減少了請求的次數,但是它也有著很大的問題,那就是耗費服務器的資源。 寫在前面 最近由于利用node重構某個項目,項目中有一個實時聊天的功能,于是就研究了一下聊天室,在線demo|源碼,歡迎大家反饋。這個聊天室的主要利用到了socket.io和express。這個...
摘要:項目簡介主要是通過做一個多人在線多房間群聊的小項目來練手全棧技術的結合運用。編譯運行開啟服務,新建命令行窗口啟動服務端,新建命令行窗口啟動前端頁面然后在瀏覽器多個窗口打開,注冊不同賬號并登錄即可進行多用戶多房間在線聊天。 項目簡介 主要是通過做一個多人在線多房間群聊的小項目、來練手全棧技術的結合運用。 項目源碼:chat-vue-node 主要技術: vue2全家桶 + socket....
摘要:分為兩個獨立的程序編譯前先確定自己服務器的地址,比如想要在自己的下運行,先獲取自己的地址,修改,里面的地址為自己的地址服務端編譯運行客戶端編譯運行服務端先運行起來后,再啟動客戶端,可以在多態機器上啟多個客戶端,互相聊天 分為兩個獨立的程序編譯前先確定自己服務器的地址,比如想要在自己的ubuntu下運行,先ip addr獲取自己的ip地址,修改chat_server.c,chat_cli...
閱讀 911·2023-01-14 11:38
閱讀 878·2023-01-14 11:04
閱讀 740·2023-01-14 10:48
閱讀 1982·2023-01-14 10:34
閱讀 942·2023-01-14 10:24
閱讀 819·2023-01-14 10:18
閱讀 499·2023-01-14 10:09
閱讀 572·2023-01-14 10:02