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命令,会发生什么?据推测,它会关闭底层操作系统套接字并阻止其他套接字对象接收和发送。
感谢您的建议,但它并没有回答我的问题。 –