2017-03-17 12 views
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ソケットを閉じて、他のソケットオブジェクトが受信して送信するのを防ぎます。

答えて

-1

あなたが提案をzmq

PyZMQ

+0

感謝を使用することができますしたい場合は、それは私の質問に答えていません。 –

関連する問題