目前就是想从电脑网卡读取单片机发送过来的数据,并且进行处理,再通过局域网转发给另外的电脑。请问要用什么模块什么方式来实现
import socket
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
packet, addr = s.recvfrom(65535)
s.sendto(data, (dest_ip, dest_port))
使用socket模块需要管理员权限,否则无法读取网卡数据。原计划在signal.signal的handler中触发TimeoutError,然后在用户代码的exception中捕获到异常,此时就可以切换到其他任务了。如下:
import signal
import time
def timeout(seconds):
def raise_timeout(func):
def timeout_handler(signum, frame):
signal.alarm(seconds)
raise TimeoutError("timeout: {} seconds".format(seconds))
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(seconds)
return func
return raise_timeout
@timeout(5)
def loop_print():
count = 0
while True:
try:
count += 1
print("current times: {}".format(count))
time.sleep(1)
except TimeoutError as e:
print(e)
if __name__ == '__main__':
loop_print()
以上实现可以满足超时自动退出需求。
但如果把loop_print中的休眠调整到10s,就发现"never come back"永远不会输出,因为signal总是会提前切换到timeout_handler,触发TimeoutError,导致time.sleep执行一半就跳到异常,所以print(“never come back”)永远无法执行
@timeout(5)
def loop_print():
count = 0
while True:
try:
count += 1
print("current times: {}".format(count))
time.sleep(10)
print("never come back")
except TimeoutError as e:
print(e)
所以在handler中raise异常是不科学的,最终代码改为:
import signal
import time
def timeout(seconds, other_thing):
def _wapper(func):
def timeout_handler(signum, frame):
other_thing()
signal.alarm(seconds)
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(seconds)
return func
return _wapper
def do_other_thing():
print("other thing done")
@timeout(5, other_thing=do_other_thing)
def loop_print():
count = 0
while True:
count += 1
print("total seconds: {}".format(count))
for i in range(7):
time.sleep(1)
print(i)
print("never come back")
if __name__ == '__main__':
loop_print()
以上代码在执行完do_other_thing后仍然会接着之前继续sleep剩余的秒数,然后执行print(“never come back”),没有破坏业务代码的逻辑(loop_print使用sleep模拟业务处理)
线程中可以通过class threading.Timer(interval, function, args=None, kwargs=None)实现一下功能