apppublic/appPublic/udp_comm.py

104 lines
2.5 KiB
Python
Raw Normal View History

2021-06-17 15:44:10 +08:00
# -*- coding:UTF-8 -*-
2022-11-09 21:37:46 +08:00
import time
2021-07-16 13:12:39 +08:00
from traceback import print_exc
2021-06-17 15:44:10 +08:00
from socket import *
2022-11-09 23:05:33 +08:00
from select import select
2021-06-17 15:44:10 +08:00
import json
from appPublic.sockPackage import get_free_local_addr
from appPublic.background import Background
2021-07-13 16:13:59 +08:00
BUFSIZE = 1024 * 64
2021-06-17 15:44:10 +08:00
class UdpComm:
2022-11-09 21:37:46 +08:00
def __init__(self, port, callback, timeout=0):
2022-11-09 23:05:33 +08:00
self.buffer = []
2021-06-17 15:44:10 +08:00
self.callback = callback
2021-06-17 15:55:15 +08:00
self.timeout = timeout
2021-06-17 15:44:10 +08:00
self.host = get_free_local_addr()[0]
self.port = port
self.udpSerSock = socket(AF_INET, SOCK_DGRAM)
# 设置阻塞
2022-11-09 23:05:33 +08:00
# self.udpSerSock.setblocking(1 if timeout > 0 else 0)
2021-06-17 15:44:10 +08:00
# 设置超时时间 1s
2022-11-09 23:05:33 +08:00
# self.udpSerSock.settimeout(timeout)
2021-06-17 15:44:10 +08:00
self.udpSerSock.bind(('' ,port))
self.run_flg = True
self.thread = Background(self.run)
self.thread.start()
def run(self):
2022-11-09 23:05:33 +08:00
sock = self.udpSerSock
2021-06-17 15:44:10 +08:00
while self.run_flg:
2022-11-10 00:50:12 +08:00
outs = []
if len(self.buffer) > 0:
outs = [sock]
in_s, out_s, exc_s = select([sock], outs, [], 0.1)
2022-11-09 23:05:33 +08:00
if sock in in_s:
b, addr = sock.recvfrom(BUFSIZE)
t = b[0]
b = b[1:]
if t == 'b':
2021-07-14 14:33:00 +08:00
self.callback(b, addr)
2022-11-09 23:05:33 +08:00
else:
2022-11-10 00:50:12 +08:00
try:
txt = b.decode('utf-8')
d = json.loads(txt)
self.callback(d, addr)
except Exception as e:
print('except:',e)
print_exc()
print(t, b)
break
2022-11-09 23:05:33 +08:00
if sock in out_s:
while len(self.buffer) > 0:
d,addr = self.buffer.pop(0)
sock.sendto(d, addr)
2022-11-10 00:50:12 +08:00
time.sleep(0.1)
self.run_flg = False
2022-11-09 23:05:33 +08:00
self.udpSerSock.close()
2021-06-17 15:44:10 +08:00
def stop(self):
self.run_flg = False
2022-11-10 00:50:12 +08:00
self.udpSerSock.close()
self.thread.join()
2021-06-17 15:44:10 +08:00
def broadcast(self, data):
broadcast_host = '.'.join(self.host.split('.')[:-1]) + '.255'
udpCliSock = socket(AF_INET, SOCK_DGRAM)
2022-11-09 23:05:33 +08:00
# udpCliSock.settimeout(1)
2021-06-17 15:44:10 +08:00
udpCliSock.bind(('', 0))
udpCliSock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
2021-07-13 16:13:59 +08:00
b = data
if not isinstance(data, bytes):
b = json.dumps(data).encode('utf-8')
2021-06-17 15:44:10 +08:00
udpCliSock.sendto(b, (broadcast_host,self.port))
2021-07-13 16:13:59 +08:00
2021-06-17 15:44:10 +08:00
def send(self,data,addr):
2021-07-13 16:13:59 +08:00
b = data
if not isinstance(data, bytes):
2022-11-09 23:05:33 +08:00
b = b'j' + json.dumps(data).encode('utf-8')
else:
b = b'b' + data
2021-06-18 12:34:35 +08:00
if isinstance(addr,list):
2021-06-18 12:29:30 +08:00
addr = tuple(addr)
2022-11-09 23:05:33 +08:00
self.buffer.append((b, addr))
2021-06-17 15:44:10 +08:00
def sends(self,data, addrs):
2022-11-09 23:05:33 +08:00
for a in addrs:
self.send(data, a)
2021-06-17 15:49:17 +08:00
if __name__ == '__main__':
import sys
def msg_handle(data, addr):
2022-11-09 23:05:33 +08:00
print('addr:', addr, 'data=', data, len(data))
2021-06-17 15:49:17 +08:00
2021-06-18 11:30:11 +08:00
port = 50000
if len(sys.argv)>1:
port = int(sys.argv[1])
d = UdpComm(port, msg_handle)
2021-06-17 15:49:17 +08:00
x = input()
while x:
2022-11-09 23:05:33 +08:00
port, data = x.split(':')
d.send(data, ('', int(port)))
2021-06-17 15:49:17 +08:00
x = input()