我正在嘗試創建一個服務器應用程式,它基本上控制多個套接字,用于通過本地網路發送的資料。
我首先在 linux 和 windows 上使用它們的庫(例如 Winsock)以及 ASIO 庫進行了一些測驗,但目標是讓它在 linux 環境中運行。
完整的應用程式將打開N個套接字(可能是異步多執行緒),并且在每個套接字接收到一些資料之前基本上什么都不做。只有到那時,服務器才會分析資料包并進行一些轉換。這是因為這些資料將具有不同的結構,并且基于此請求了不同的連接(至少我被要求這樣做)。所以在固定的時間,我會有N個可用的資料包,然后由服務器“重新組合”。
本質上,每個套接字都在某種程度上“系結”到它應該接收的資料型別。
現在的問題是我不明白要為這種情況實施哪種解決方案,因為我“被迫”使用 UDP 協議以及使用不同的套接字。據我所知,對于這種東西,使用 TCP 協議,這樣每個套接字對都可以建立連接并做自己的事情。
此外,我不能使用單個 UDP 套接字來接收所有內容。這主要是因為: A- 我被問到不同的問題;B-即使資料包的時間安排不是一個真正的問題,我也無法將它們全部混合在一起,因為它需要從客戶端發送額外的資訊(我無法控制)。
事實上,現在我明白為什么沒有那么多關于 UDP 場景的檔案了。我很樂意切換到 TCP,這樣至少我會大致了解該怎么做,但目前我做不到。
你能幫我更好地了解情況嗎?
uj5u.com熱心網友回復:
正如評論所建議的,您可以使用該select功能監控多個埠。它需要埠串列來檢查可讀性、可寫性或錯誤,并回傳處于請求狀態的埠串列。
下面是一個觀察 5 個埠以提高可讀性的示例,并在所有 5 個埠都收到內容時退出:
import socket
import select
N = 5
base_port = 5000
# Create N sockets and bind to ports 5000 to 5000 N-1:
socks = [socket.socket(type=socket.SOCK_DGRAM) for _ in range(N)]
for i,s in enumerate(socks):
s.bind(('',base_port i))
# Flags to track that something was received on a particular port
got = [False] * N
while not all(got):
# Watch all N sockets for readability only
readable,writable,errors = select.select(socks,[],[])
# Only a socket that has something to read will be in "readable"
for s in readable:
port = s.getsockname()[1] # which port was it
data,addr = s.recvfrom(4096)
print(f'From {port}: {data}')
got[port-5000] = True
print("Got'em all!")
演示(客戶端)
>>> from socket import *
>>> s=socket(type=SOCK_DGRAM)
>>> s.sendto(b'abc',('localhost',5001))
3
>>> s.sendto(b'abc',('localhost',5002))
3
>>> s.sendto(b'abc',('localhost',5003))
3
>>> s.sendto(b'abc',('localhost',5004))
3
>>> s.sendto(b'abc',('localhost',5000))
3
演示(服務器)
From 5001: b'abc'
From 5002: b'abc'
From 5003: b'abc'
From 5004: b'abc'
From 5000: b'abc'
Got'em all!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/475867.html
