[英]Sending and receiving using sockets python
我正在嘗試創建一個 function 來通過套接字客戶端和服務器發送和接收信息。 看來我的代碼在某種程度上被阻塞了。 在代碼中,我的 for 循環中的第一個命令迭代被執行,但隨后進程被阻塞。 有沒有人有任何建議如何使用線程或多線程來做到這一點?
我的代碼如下:
import socket
import json
import sys
import time
import select
import queue
Ni_Rio_IP= "172.22.11.2"
Ni_Base_IP= "172.22.11.1"
class AliceRio:
def __init__(self, ip_rio, ip_pc):
self.ip_rio = ip_rio
AliceRio.udp_port_rio = 60006
self.ip_pc = ip_pc
AliceRio.udp_port_pc = 50005
AliceRio.json= '{"Dest":"","Name":"","Time":"","Val":{"Str":[],"Pos":[[]],"Data":[[]]},"IP":0,"Port":0,"RT error":{"status":false,"code":0,"source":""}}'
AliceRio.dict= json.loads(self.json)
def PrintUDP(self):
print("RIO IP: %s" % self.ip_rio)
print("RIO UDP port: %s" % self.udp_port_rio)
print("PC IP: %s" % self.ip_pc)
print("PC UDP port: %s" % self.udp_port_pc)
def SendRec(self, send_str):
# Set up socket for sending
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Internet, UDP
sock.sendto(bytes(send_str, 'utf-8'), (self.ip_rio, self.udp_port_rio))
sock.close()
print('got here')
# Set up socket for receiving
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # Internet, UDP
sock.bind((self.ip_pc, self.udp_port_pc))
rec_str, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print('got here2')
sock.close()
return rec_str
def Receive(self, rec_str):
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # Internet, UDP
sock.bind((self.ip_pc, self.udp_port_pc))
rec_str, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
sock.close()
return rec_str
def Send(self, send_str):
# Set up socket for sending
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Internet, UDP
sock.sendto(bytes(send_str, 'utf-8'), (self.ip_rio, self.udp_port_rio))
sock.close()
#return rec_str
def Aim(self, aim_perc):
if aim_perc < 0 or aim_perc > 100: return "aim_perc out of range"
send_dict=AliceRio.dict
send_dict["Dest"]='Rio'
send_dict["Name"]='Laser Control'
Laser_Mode=1
Simmer_A=0
Pulse_A= 0
Pulse_ms= 20
send_dict["Val"]["Str"]=[str(Laser_Mode), str(aim_perc), str(Simmer_A), str(Pulse_A), str(Pulse_ms)]
send_json=json.dumps(send_dict)
# send it out
self.SendRec(send_json)
rec_json= self.SendRec(send_json)
rec_dict=json.loads(rec_json)
return "Aim laser now at " + rec_dict["Val"]["Str"][1] +'%'
def PWM_Laser_Fan(self, fan_perc):
send_dict=AliceRio.dict
send_dict["Dest"]='Rio'
send_dict["Name"]='PWM Laser'
send_dict["Val"]["Str"][0]=str(fan_perc)
send_json=json.dumps(send_dict)
# send it out
rec_json= self.SendRec(send_json)
rec_dict=json.loads(rec_json)
return rec_dict["Val"]["Str"][0]
def Poll(self):
send_dict=AliceRio.dict
send_dict["Dest"]='Rio'
send_dict["Name"]='Poll'
send_json=json.dumps(send_dict)
# send it out
rec_json= self.SendRec(send_json)
rec_dict=json.loads(rec_json)
if rec_dict["Val"]["Data"][0][0]==0: pid_mode='off'
else: pid_mode='PID'
print('PID mode:', pid_mode)
print('Pos X:', rec_dict["Val"]["Data"][0][1])
print('Pos Y:', rec_dict["Val"]["Data"][0][2])
print('Home:', rec_dict["Val"]["Data"][0][3])
print('Enabled:', rec_dict["Val"]["Data"][0][4])
def PIDControl(self, pid_mode,pid_center):
if pid_mode=="off": mode= 0
elif pid_mode=="PID":mode =1
else: return "pid_mode not valid"
if pid_center[0] not in range(-2048,2048): return "center x-pos not in range"
if pid_center[1] not in range(-2048,2048): return "center y-pos not in range"
send_dict=AliceRio.dict
send_dict["Dest"]='Rio'
send_dict["Name"]='PID Control'
send_dict["Val"]["Str"]=[str(mode), str(pid_center[0]), str(pid_center[1])]
send_json=json.dumps(send_dict)
# send it out
rec_json= self.SendRec(send_json)
rec_dict=json.loads(rec_json)
return "PID mode now at " + rec_dict["Val"]["Str"][0]
Alice1 = AliceRio(Ni_Rio_IP, Ni_Base_IP)
Alice1.PrintUDP()
for i in range(10):
Alice1.Aim((i*10)+10)
time.sleep(0.2)
我建議學習使用Pdb並跟蹤程序的執行以找到它被捕獲的位置。
此外,在使用 sockets 學習/開發時,我發現在開始時為您的客戶端和服務器設置單獨的程序會有所幫助,因此您可以看到雙方如何處理交換而不是開始線程路由,因為日志記錄可能會變得混亂,祝你好運!
模塊線程在這種情況下確實有幫助。 我們可以創建一個線程來接收傳入的消息。 並且當收到新消息時,線程會觸發一個事件來通知等待方法SendRec
。
import sys
import socket
import json
import threading
import time
class AliceRio:
def __init__(self, .....):
# .........
self.s_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.s_in.bind((self.ip_pc, self.udp_port_pc))
self.evt = threading.Event()
self.last_msg = None
def _recv(self):
while True:
msg, _ = self.s_in.recvfrom(1024)
self.last_msg = msg
self.evt.set()
def SendRec(self, send_str):
if not hasattr(self, 'th_recv'):
th = threading.Thread(target=self._recv)
th.setDaemon(True)
th.start()
self.th_recv = th
self.evt.clear()
rio_endpoint = (self.ip_rio, self.udp_port_rio)
s_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s_out.sendto(bytes(send_str, 'utf-8'), rio_endpoint)
s_out.close()
if self.evt.wait(timeout=15.0) and self.last_msg:
return self.last_msg
raise Exception('timeout waiting for response.')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.