2
我已經計劃設計一個UDP服務器,其工作原理如下:我將與位於防火牆後面的客戶端進行通信,並且需要能夠隨時發送數據。因此,客戶端將首先發起與我的連接,並通過定期發送保持活動的數據包來定期保持連接處於活動狀態。當我收到一個,我需要承認它。同時,如果我有任何數據要發送,我需要立即發送。我已經把下面的測試代碼:Python套接字對象是否線程安全?
import threading
import queue
import socket
import time
class SharedAddress():
def __init__(self):
self.lock = threading.Lock()
self.addr =()
def set_addr(self, addr):
self.lock.acquire()
self.addr = addr
self.lock.release()
def get_addr(self):
self.lock.acquire()
addr = self.addr
self.lock.release()
return addr
class Reader(threading.Thread):
def __init__(self, socket, shared_address):
super().__init__(name='Reader Thread')
self.socket = socket
self.shared_address = shared_address
def run(self):
while True:
# Wait for data from the client
data, addr = self.socket.recvfrom(4096)
#print("Received data from {}".format(addr))
# Echo it back
self.socket.sendto(data, addr)
self.shared_address.set_addr(addr)
class Writer(threading.Thread):
def __init__(self, socket, shared_address):
super().__init__(name='Writer Thread')
self.socket = socket
self.tx_queue = queue.Queue()
self.shared_address = shared_address
def run(self):
while True:
# Wait for data to be received
data = self.tx_queue.get()
# Send it to the client
addr = self.shared_address.get_addr()
if addr:
self.socket.sendto(data, addr)
### Main loop
# Create the socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 2000))
sa = SharedAddress()
r = Reader(s, sa)
w = Writer(s, sa)
r.start()
w.start()
while True:
w.tx_queue.put(b'>>Hi this is a message<<\n')
time.sleep(0.1)
r.join()
w.join()
print("Program ended")
雖然代碼出現的工作,我很擔心的是,我使用的是從兩個不同的線程在同一socket對象沒有任何類型的鎖。然後我修改Writer類來創建它自己的套接字對象:
class Writer(threading.Thread):
def __init__(self, shared_address):
super().__init__(name='Writer Thread')
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.tx_queue = queue.Queue()
self.shared_address = shared_address
這也似乎工作得很好。我的問題如下:
- 套接字對象線程安全嗎?
- 如果您在Python中創建多個UDP套接字對象並使用它們將數據發送到相同的地址,它們實際上是否最終引用了相同的基礎連接對象?
- 如果我對其中一個套接字對象調用close命令,會發生什麼?據推測,它會關閉底層操作系統套接字並阻止其他套接字對象接收和發送。
感謝您的建議,但它並沒有回答我的問題。 –