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")
コードが動作するように見えますが、私はロックの任意の並べ替えずに2つの異なるスレッドから同じソケットオブジェクトを使用していたという事実が心配です。次に、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
これはうまくいくようです。私の質問は以下の通りです:
- ソケットオブジェクトは安全ですか?
- 複数のUDPソケットオブジェクトをPythonで作成し、それらを使用して同じアドレスにデータを送信すると、それらは実際には同じ基本接続オブジェクトを参照することになりますか?
- ソケットオブジェクトの1つでcloseコマンドを呼び出すとどうなりますか?おそらく、それは潜在的なOSソケットを閉じて、他のソケットオブジェクトが受信して送信するのを防ぎます。
感謝を使用することができますしたい場合は、それは私の質問に答えていません。 –