欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Python socket實(shí)現(xiàn)簡易網(wǎng)絡(luò)聊天室

 更新時(shí)間:2022年07月04日 07:55:53   作者:Python 集中營  
本文主要介紹了基于Python socket實(shí)現(xiàn)簡易網(wǎng)絡(luò)聊天室,本文將通過pyqt5作為桌面應(yīng)用框架,socket作為網(wǎng)絡(luò)編程的框架,從而實(shí)現(xiàn)包括客戶端和服務(wù)端的網(wǎng)絡(luò)聊天室的GUI應(yīng)用,需要的可以參考一下

在這個(gè)周末剛剛寫出來的python桌面應(yīng)用--網(wǎng)絡(luò)聊天室,主要通過pyqt5作為桌面應(yīng)用框架,socket作為網(wǎng)絡(luò)編程的框架,從而實(shí)現(xiàn)包括客戶端和服務(wù)端的網(wǎng)絡(luò)聊天室的GUI應(yīng)用,希望可以一起學(xué)習(xí)、一起進(jìn)步!

應(yīng)用包括服務(wù)端server_ui.py、客戶端client_ui.py兩個(gè)python模塊實(shí)現(xiàn),并且在pyqt5的使用過程中都使用QThread多線程應(yīng)用以及基本的UI頁面布局。開始之前通過一個(gè)動態(tài)圖來觀察一下socket服務(wù)端、socket客戶端通信的實(shí)現(xiàn)效果。

1.socket_ui.py 服務(wù)端

1-1. 依賴引用

在socket服務(wù)端的實(shí)現(xiàn)過程中,除了pyqt5相關(guān)的UI界面的引用外,還包括time、threading、sys、socket等輔助模塊來一起實(shí)現(xiàn)socket服務(wù)端的桌面應(yīng)用程序。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys

from QCandyUi import CandyWindow

# 導(dǎo)入 socket 通訊模塊
import socket
# 導(dǎo)入時(shí)間管理模塊
import time
# 導(dǎo)入多線程模塊
import threading

1-2. 實(shí)現(xiàn)過程

在服務(wù)端的業(yè)務(wù)實(shí)現(xiàn)上面,我們依然是按照之前的GUI實(shí)現(xiàn)方式,采用主線程用來實(shí)現(xiàn)頁面布局,子線程QThread來實(shí)現(xiàn)業(yè)務(wù)邏輯的方式來進(jìn)行實(shí)現(xiàn)的,socket的服務(wù)端通信業(yè)務(wù)都是在子線程ServerThread中編寫的。下面是socket服務(wù)端桌面應(yīng)用實(shí)現(xiàn)的全部代碼塊,copy到自己的ide中即可直接啟動使用。

class ServerUI(QWidget):
    def __init__(self):
        super(ServerUI, self).__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('socket 服務(wù)端  公眾號:[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('消息展示區(qū)域...')
        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('最大監(jiān)聽個(gè)數(shù) ')
        self.lis_num_txt = QLineEdit()
        self.lis_num_txt.setPlaceholderText('10')

        self.close_cli_label = QLabel()
        self.close_cli_label.setText('客戶端關(guān)閉指令 ')
        self.close_cli_txt = QLineEdit()
        self.close_cli_txt.setPlaceholderText('exit,客戶端發(fā)送相應(yīng)指令則關(guān)閉')

        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('開啟服務(wù)端')
        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):
        '''
        槽函數(shù):向文本瀏覽器中寫入內(nèi)容
        :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('準(zhǔn)備啟動socket服務(wù)端...')
        # 創(chuàng)建服務(wù)端 socket
        socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 綁定服務(wù)地址、端口
        address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip()))
        socket_server.bind(address)
        # 設(shè)置監(jiān)聽最大等待數(shù)
        socket_server.listen(int(self.parent.lis_num_txt.text().strip()))
        self.message.emit("服務(wù)已經(jīng)啟動,正在等待客戶端連接...")
        while True:
            # 設(shè)置睡眠時(shí)間
            time.sleep(0.1)
            # 允許客戶端連接
            client, info = socket_server.accept()
            self.client, self.info = client, info
            # 啟用新線程調(diào)用消息處理
            thread = threading.Thread(target=self.catch_message)
            # 設(shè)置為守護(hù)線程
            thread.setDaemon(True)
            # 開啟線程執(zhí)行
            thread.start()

    def catch_message(self):
        self.client.send("歡迎來到網(wǎng)絡(luò)聊天室".encode('utf-8'))
        self.message.emit("客戶端信息:" + str(self.info))
        close_cli = self.parent.close_cli_txt.text().strip()
        while True:
            try:
                #  接收客戶端消息、接收最大長度為 1024,并進(jìn)行 utf-8 解碼
                message = self.client.recv(1024).decode('utf-8')
                # 校驗(yàn)是否關(guān)閉客戶端
                if not message and close_cli == message:
                    self.client.close()
                    self.message.emit("當(dāng)前客戶端已關(guān)閉!")
                    break
                self.message.emit("接收到消息:" + message)
                # 將消息進(jìn)行 utf-8 編碼后發(fā)給客戶端
                rcv = "服務(wù)端成功接收消息:" + message
                self.client.send(rcv.encode('utf-8'))
            except Exception as e:
                self.client.send("服務(wù)端處理消息異常!".encode('utf-8'))
                break


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = CandyWindow.createWindow(ServerUI(), theme='blueGreen', title='socket 服務(wù)端  公眾號:[Python 集中營]',
                                 ico_path='hi.ico')
    w.show()
    sys.exit(app.exec_())

1-3. 實(shí)現(xiàn)效果

2.client_ui.py 客戶端

2-1. 依賴引用

在socket客戶端的實(shí)現(xiàn)過程中,除了pyqt5相關(guān)的UI界面的引用外,還包括sys、socket等輔助模塊來一起實(shí)現(xiàn)socket服務(wù)端的桌面應(yīng)用程序,相比服務(wù)端來說,客戶端并沒有使用多線程threading模塊。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys

from QCandyUi import CandyWindow

# 導(dǎo)入socket 通信模塊
import socket

2-2. 實(shí)現(xiàn)過程

客戶端的實(shí)現(xiàn)過程和服務(wù)端server_ui.py實(shí)現(xiàn)是基本相似的,同樣也使用到了pyqt5的QThread的子線程應(yīng)用,唯一不同的是socket客戶端通信方式跟服務(wù)端不大相同,同樣將下面的代碼塊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('消息展示區(qū)域...')
        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('發(fā)送消息內(nèi)容...')

        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('發(fā)送消息')
        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):
        '''
        槽函數(shù):向文本瀏覽器中寫入內(nèi)容
        :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()
            # 將控制臺輸入消息進(jìn)行 utf-8 編碼后發(fā)送
            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("發(fā)送消息異常:" + str(e))

    def connect_serv(self):
        try:
            self.message.emit("正在創(chuàng)建客戶端socket...")
            # 創(chuàng)建客戶端 socket
            self.socket_client = socket.socket()
            # 連接服務(wù)端
            address = (self.parent.ip_txt.text().strip(), int(self.parent.port_txt.text().strip()))
            self.socket_client.connect(address)
            self.message.emit("服務(wù)端連接成功...")
            # 接收服務(wù)端消息并進(jìn)行 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. 實(shí)現(xiàn)效果

以上就是基于Python socket實(shí)現(xiàn)簡易網(wǎng)絡(luò)聊天室的詳細(xì)內(nèi)容,更多關(guān)于Python socket網(wǎng)絡(luò)聊天室的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談Python中eval的強(qiáng)大與危害

    淺談Python中eval的強(qiáng)大與危害

    這篇文章主要介紹了Python中eval的強(qiáng)大與危害,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • python升級pip及失敗處理方式

    python升級pip及失敗處理方式

    這篇文章主要介紹了python升級pip及失敗處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Django Admin設(shè)置應(yīng)用程序及模型順序方法詳解

    Django Admin設(shè)置應(yīng)用程序及模型順序方法詳解

    這篇文章主要介紹了Django Admin設(shè)置應(yīng)用程序及模型順序方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • python如何求取指定范圍內(nèi)的質(zhì)數(shù)

    python如何求取指定范圍內(nèi)的質(zhì)數(shù)

    這篇文章主要介紹了python如何求取指定范圍內(nèi)的質(zhì)數(shù)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 如何利用python之wxpy模塊玩轉(zhuǎn)微信

    如何利用python之wxpy模塊玩轉(zhuǎn)微信

    這篇文章主要介紹了利用python之wxpy模塊玩轉(zhuǎn)微信,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Python中with...as...的使用方法

    Python中with...as...的使用方法

    with是從Python2.5引入的一個(gè)新的語法,它是一種上下文管理協(xié)議,目的在于從流程圖中把 try,except 和finally 關(guān)鍵字和資源分配釋放相關(guān)代碼統(tǒng)統(tǒng)去掉,簡化try….except….finlally的處理流程。具體內(nèi)容請看下面小編詳細(xì)的介紹
    2021-09-09
  • Django實(shí)現(xiàn)隨機(jī)圖形驗(yàn)證碼的示例

    Django實(shí)現(xiàn)隨機(jī)圖形驗(yàn)證碼的示例

    這篇文章主要介紹了Django實(shí)現(xiàn)隨機(jī)圖形驗(yàn)證碼的示例,幫助大家更好的學(xué)習(xí)和使用django框架,感興趣的朋友可以了解下
    2020-10-10
  • selenium在scrapy中的使用代碼

    selenium在scrapy中的使用代碼

    本文給大家分享selenium在scrapy中的使用代碼,使用selenium可以很好的幫助我們獲取一些重要數(shù)據(jù)信息,本文通過代碼給大家詳細(xì)介紹,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 簡單的抓取淘寶圖片的Python爬蟲

    簡單的抓取淘寶圖片的Python爬蟲

    這篇文章主要介紹了簡單的抓取淘寶圖片的Python爬蟲,方法比較簡單,推薦給小伙伴們參考下。
    2014-12-12
  • python與php實(shí)現(xiàn)分割文件代碼

    python與php實(shí)現(xiàn)分割文件代碼

    本文給大家分享的是兩個(gè)分別使用python和php實(shí)現(xiàn)的將文件分割成小文件的代碼,非常的實(shí)用有需要的小伙伴可以參考下
    2017-03-03

最新評論