服务端代码:
import socket
import threading
import logging
import datetime
logging.basicConfig(format='%(thread)s %(threadName)s %(message)s',level=logging.INFO)
class ChatServerUdp:
def __init__(self,ip='127.0.0.1',port=9988):
self.sock = socket.socket(type=socket.SOCK_DGRAM)
self.addr = (ip,port)
self.event = threading.Event()
self.clients = {}
self.interval = 10
def start(self):
self.sock.bind(self.addr)
threading.Thread(name='recv',target=self._recv,daemon=True).start()
def stop(self):
self.sock.close()
self.event.set()
def _recv(self):
while not self.event.is_set():
print(self.clients)
data,clientaddr = self.sock.recvfrom(1024)
logging.info('{} {}'.format(data.decode(),clientaddr))
data = data.decode().strip()
current = datetime.datetime.now().timestamp()
if data == '^hb^':
self.clients[clientaddr] = current
continue
elif data == 'quit':
self.clients.pop(clientaddr)
continue
elif data == 'come':
self.clients[clientaddr] = current
continue
self.clients[clientaddr] = current
msg = 'ack {}'.format(data)
n = datetime.datetime.now().timestamp()
lst = set()
for caddr,ts in self.clients.items():
if n - ts <= self.interval:
print(self.clients)
self.sock.sendto(msg.encode(),caddr)
else:
lst.add(caddr)
for x in lst:
self.clients.pop(x)
cs = ChatServerUdp()
cs.start()
while True:
cmd = input('>>>').strip()
if cmd == 'quit':
cs.stop()
break
客户端代码:
import threading
import socket
import logging
logging.basicConfig(format='%(thread)s %(threadName)s %(message)s',level=logging.INFO)
class ChatClientUdp:
def __init__(self,ip='127.0.0.1',port=9988,interval=5):
self.sock = socket.socket(type=socket.SOCK_DGRAM)
self.addr = (ip,port)
self.interval = interval
self.event = threading.Event()
def start(self):
self.sock.sendto(b'come',self.addr)
threading.Thread(name='revfrom',target=self._recv,daemon=True).start()
threading.Thread(name='hb',target=self._sendhb,daemon=True).start()
def _recv(self):
while not self.event.is_set():
data,srvaddr = self.sock.recvfrom(1024)
logging.info('{} {}'.format(data.decode(),srvaddr))
def send(self,data='quit'):
self.sock.sendto(data.encode(),self.addr)
def _sendhb(self):
msg = '^hb^'
while not self.event.wait(self.interval):
self.sock.sendto(msg.encode(),self.addr)
def stop(self):
self.sock.close()
cc = ChatClientUdp()
cc.start()
while True:
cmd = input('>>>').strip()
if cmd == 'quit':
cc.send('quit')
cc.stop()
break
cc.send(cmd)
运行结果:
服务端:
{}
>>>{('127.0.0.1', 36163): 1563519226.766523}
140093223106304 recv ^hb^ ('127.0.0.1', 36163)
{('127.0.0.1', 36163): 1563519231.767525}
140093223106304 recv ^hb^ ('127.0.0.1', 36163)
140093223106304 recv ^hb^ ('127.0.0.1', 36163)
{('127.0.0.1', 36163): 1563519236.766653}
{('127.0.0.1', 36163): 1563519237.175765}
{('127.0.0.1', 36163): 1563519237.175765}
140093223106304 recv hello python ('127.0.0.1', 36163)
{('127.0.0.1', 36163): 1563519241.766967}
140093223106304 recv ^hb^ ('127.0.0.1', 36163)
{}
140093223106304 recv quit ('127.0.0.1', 36163)
客户端:
>>>hello python
>>>139819724605184 revfrom ack hello python ('127.0.0.1', 9988)
quit