#客户端编写
import threading
import logging
import socket
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
socke =socket.socket(type=socket.SOCK_DGRAM)
ip ='127.0.0.1'
port =10001
addr = (ip,port)
msg ="kang!!!!!!!!".encode()
socke.connect(addr)
socke.send(msg)
data,caddr =socke.recvfrom(1024)
#data =socke.recv(1024)
print(data,caddr)
-----------------------------------------------------
UDP服务器程序:
类实现:
import threading
import socket
import logging
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
class ChatServerUDP:
def __init__(self,ip='127.0.0.1',port=8800):
self.socke =socket.socket(type=socket.SOCK_DGRAM)
self.addr =(ip,port)
self.client ={}
self.event =threading.Event()
self.clients=set() #记录客户端
def start(self):
self.socke.bind(self.addr)
threading.Thread(target=self._recv,name="recv_accept").start()
def stop(self):
self.socke.close()
self.event.set()
def _recv(self):
while not self.event.is_set():
data,clientinfo =self.socke.recvfrom(1024)
data =data.decode().strip()
if data == "kang": #注册信息,把客户端加入set,记录客户端IP及PORT
self.clients.add(clientinfo)
continue
if data == "quit":
self.clients.remove(clientinfo)
continue
msg ="ack --->{}".format(data)
logging.info(msg)
self.clients.add(clientinfo)
for cli in self.clients:
self.socke.sendto(msg.encode(),cli)
def ShowThread():
while not threading.Event().wait(5):
logging.info(threading.enumerate())
threading.Thread(target=ShowThread,daemon=True,name="thread_showthread").start()
运行模块:main.py
import threading
from networksocke import ChatServerUDP
import logging
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
def main():
cs = ChatServerUDP()
cs.start()
while True:
cmd = input(">>>").strip()
if cmd == "quit":
cs.stop()
break
if __name__ == "__main__":
main()
------------------------------------------------------------
UPD客户程序:
import threading
import logging
import socket
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
class ChatClientUDP:
def __init__(self,ip='127.0.0.1',port=8800):
self.socke =socket.socket(type=socket.SOCK_DGRAM)
self.addr =(ip,port)
self.event =threading.Event()
def start(self):
self.send('kang') #先发送一个注册信息,让服务器记录客户端ip及端口
threading.Thread(target=self._recv,name="recv_thread").start()
def _recv(self):
while not self.event.is_set():
data,addr =self.socke.recvfrom(1024)
logging.info("{},{}".format(data,addr))
def send(self,data="quit"):
self.socke.sendto(data.encode(),self.addr)
def stop(self):
self.socke.close()
cs =ChatClientUDP()
cs.start()
def main():
cs = ChatClientUDP()
cs.start()
while True:
cmd = input(">>>").strip()
if cmd == "quit":
cs.stop()
cs.send()
break
cs.send(cmd)
if __name__ == "__main__":
main()
---------------------------------------------
加入心跳机制:
import threading
import socket
import logging
import datetime
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
class ChatServerUDP:
def __init__(self,ip='127.0.0.1',port=8800):
self.socke =socket.socket(type=socket.SOCK_DGRAM)
self.addr =(ip,port)
self.event =threading.Event()
self.clients={} #记录客户端
self.interval = 10
def start(self):
self.socke.bind(self.addr)
threading.Thread(target=self._recv,name="recv_accept").start()
def stop(self):
self.socke.close()
self.event.set()
def _recv(self):
while not self.event.is_set():
data,clientinfo =self.socke.recvfrom(1024)
data =data.decode().strip()
currt =datetime.datetime.now().timestamp()
if data == "^hb": #服务器接收心跳信息
self.clients[clientinfo] =currt
continue
elif data == "kang": #注册信息,把客户端加入set,记录客户端IP及PORT
self.clients[clientinfo] =currt
continue
elif data == "quit":
self.clients.pop(clientinfo)
continue
msg ="ack --->{}".format(data)
logging.info(msg)
self.clients[clientinfo] =currt
newt = datetime.datetime.now().timestamp()
lset =set() #临时存储要pop的对象
for cli,ts in self.clients.items():
if newt - ts < self.interval:
self.socke.sendto(msg.encode(),cli)
else:
lset.add(cli)
for i in lset:
self.clients.pop(i)
)
def ShowThread():
while not threading.Event().wait(5):
logging.info(threading.enumerate())
threading.Thread(target=ShowThread,daemon=True,name="thread_showthread").start()
客户端:
import threading
import logging
import socket
FORMAT = "%(asctime)s %(thread)d %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT)
class ChatClientUDP:
def __init__(self,ip='127.0.0.1',port=8800,interval=5):
self.socke =socket.socket(type=socket.SOCK_DGRAM)
self.addr =(ip,port)
self.event =threading.Event()
self.interval =interval
def start(self):
self.send('kang') #先发送一个注册信息,让服务器记录客户端ip及端口
threading.Thread(target=self._recv,name="recv_thread").start()
threading.Thread(target=self._sendhb,name="hb_thread",daemon=True).start() #心跳机制启动
def _recv(self):
while not self.event.is_set():
data,addr =self.socke.recvfrom(1024)
logging.info("{},{}".format(data,addr))
def send(self,data="quit"):
self.socke.sendto(data.encode(),self.addr)
def stop(self):
self.socke.close()
#增加一个心跳机制方法
def _sendhb(self):
msg ="^hb"
while not self.event.wait(self.interval):
self.socke.sendto(msg.encode(),self.addr)
cs =ChatClientUDP()
cs.start()
def main():
cs = ChatClientUDP()
cs.start()
while True:
cmd = input(">>>").strip()
if cmd == "quit":
cs.stop()
cs.send()
break
cs.send(cmd)
if __name__ == "__main__":
main()
--------------------------------------