2017-03-17 41 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") 

雖然代碼出現的工作,我很擔心的是,我使用的是從兩個不同的線程在同一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命令,會發生什麼?據推測,它會關閉底層操作系統套接字並阻止其他套接字對象接收和發送。

回答

-1

如果你願意,你可以使用ZMQ

PyZMQ

+0

感謝您的建議,但它並沒有回答我的問題。 –