在這篇部落格中,我們將使用 Python 實作一個功能齊全的 TCP 聊天室。我們將擁有一台伺服器來託管房間,以及多個客戶端連接到它並相互通信。
傳輸控制協議是一種面向連接的通訊協議,有助於透過網路在不同設備之間交換訊息。
為了實現我們的聊天室,我們將使用客戶端-伺服器架構。這意味著我們將擁有多個客戶端(使用者)和一台中央伺服器來託管所有內容並為這些客戶端提供資料。
1.為了設定我們的基礎伺服器,我們需要匯入兩個函式庫,也就是套接字和執行緒。套接字庫將用於建立和設定網路連線,執行緒庫是同時執行各種任務所必需的。
import socket import threading
2. 下一個任務是定義我們的伺服器資料並初始化我們的套接字。我們需要主機的 IP 位址和伺服器的可用連接埠號碼。在本部落格中,我們將使用位址 127.0.0.1,即我們的 localhost 和連接埠 5500。
連接埠號碼無關緊要,但您必須確保您使用的連接埠是免費且未保留。如果您在實際伺服器或虛擬機器上執行此聊天室,請將聊天室伺服器的 IP 位址指定為虛擬機器或伺服器的主機 IP 位址。
查看此保留連接埠號碼清單以取得更多資訊。
# Server Data host = '127.0.0.1' port = 5500
3. 當我們定義套接字時,我們需要傳遞兩個參數。這些定義了我們要使用的套接字類型。第一個 (AF_INET) 顯示我們使用的是互聯網套接字而不是 unix 套接字。第二個參數代表我們要使用的協定。 SOCK_STREAM 表示我們正在使用 TCP。
定義套接字後,我們透過傳遞包含這兩個值的元組將其綁定或附加到我們的主機和指定連接埠。然後我們將伺服器置於監聽模式,以便它等待客戶端連接並發送訊息..
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
4.我們還將建立兩個空列表,稍後我們將用它們來儲存連接的客戶端及其暱稱。
import socket import threading
5.現在我們將定義所有有助於我們廣播訊息的函數。它將向每個連接的客戶端發送一條訊息,因此會出現在客戶端清單中。
# Server Data host = '127.0.0.1' port = 5500
6.現在我們將建立一個handle()函數。該函數將負責處理來自客戶端的消息。該函數將在 while 循環中運行。該函數將接受客戶端作為參數並無限循環地處理它,直到發生錯誤或客戶端本身斷開連接。
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
7. 現在我們必須接收來自客戶端的訊息並將其廣播給所有連接的客戶端。因此,當一個客戶端發送一條訊息時,其他人都可以透過broadcast()函數看到該訊息。現在,如果由於某種原因與該用戶端的連線出現錯誤,我們將刪除它及其暱稱,關閉連線並廣播該用戶端已離開聊天。
# Lists For Clients and Their Nicknames clients = [] nicknames = []
當我們準備好運行我們的伺服器時,我們將執行這個接收函數。一旦客戶端連接到伺服器,它就會向伺服器發送字串“NAME”,這將告訴客戶端請求其暱稱。之後,它等待回應並將具有相應暱稱的客戶端附加到清單中,並為該特定客戶端的handle()函數啟動一個線程。
8. 現在我們可以運行這個函數,我們的伺服器就完成了。
# Sending Messages To All Connected Clients def broadcast(message): for client in clients: client.send(message)
現在我們要實現我們的客戶端。為此,我們將再次需要導入相同的庫。
# Handling Clients def handle(client): while True: try: # Broadcasting Messages message = client.recv(1024) broadcast(message) except: # Removing And Closing Clients index = clients.index(client) clients.remove(client) client.close() nickname = nicknames[index] broadcast('{} left!'.format(nickname).encode('ascii')) nicknames.remove(nickname) break
1. 客戶端的第一步是選擇暱稱並連接到我們的伺服器。我們需要知道伺服器運行的確切位址和連接埠。作為客戶端,我們連接到現有伺服器,而不是綁定資料和監聽。
# Receiving `Function def receive(): while True: # Accept Connection client, address = server.accept() print("Connected with {}".format(str(address))) # Request And Store Nickname client.send('NAME'.encode('ascii')) nickname = client.recv(1024).decode('ascii') nicknames.append(nickname) clients.append(client) # Print And Broadcast Nickname print("Nickname is {}".format(nickname)) broadcast("{} joined!".format(nickname).encode('ascii')) client.send('Connected to server!'.encode('ascii')) # Start Handling Thread For Client thread = threading.Thread(target=handle, args=(client,)) thread.start()
2. 現在,客戶端需要有兩個同時執行的執行緒。第一個將不斷從伺服器接收數據,第二個將向伺服器發送我們自己的訊息。
receive()
這裡又出現了一個無限的 while 迴圈。它不斷嘗試接收訊息並將其列印到螢幕上。但是,如果訊息是“NAME”,它不會列印它,而是將其暱稱發送到伺服器。
書寫功能相當短。它還以無限循環運行,始終等待用戶的輸入。一旦獲得一些,它就會將其與暱稱結合並發送給伺服器。
3.我們需要做的最後一件事是啟動兩個運行這兩個函數的執行緒。
import socket import threading
現在我們完成了。我們有一個功能齊全的伺服器和可以連接到它並相互通訊的工作客戶端。
我們來測試一下吧。請記住,我們始終需要先啟動伺服器,否則客戶端無法連接到不存在的主機。
*伺服器日誌:*
# Server Data host = '127.0.0.1' port = 5500
*客戶端一日誌:*
# Start the Server server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen()
*客戶端二日誌:*
# Lists For Clients and Their Nicknames clients = [] nicknames = []
在此處找到完整程式碼:https://github.com/rajatuiwebdev/tcp-chatroom-in-python
在 Instagram 上追蹤我: https://instagram.com/rajatrajput.dev
在 LinkedIn 上追蹤我: https://linkedin.com/in/rajatrajput2004
以上是Python 中的 TCP 聊天室的詳細內容。更多資訊請關注PHP中文網其他相關文章!