首页 > 其他 > 详细

44.socket编程(三)

时间:2021-06-11 12:13:08      阅读:23      评论:0      收藏:0      [点我收藏+]

 

4:线程级别的UDPServer

 

 

UDP服务器端

 

    import threading
    import socket
    class Server:
        # 初始化:绑定端口
        def __init__(self, ip=127.0.0.1, port=9000):
            self.socket_instance = socket.socket(type=socket.SOCK_DGRAM)
            self.addr = (ip, port)
            self.event = threading.Event()
            self.clients = set()
            self.__run()
        def __run(self):
            # 绑定地址,监听地址
            self.socket_instance.bind(self.addr)
            # 将阻塞的__recvfrom()方法放到线程执行
            threading.Thread(target=self.__recvfrom, name=recvfrom).start()
        def __recvfrom(self):
            while not self.event.is_set():
                try: # 这里捕获异常是由于一旦关闭socket,那么data, addr不会获取到值,那么应该捕获异常,给data, addr赋值
                    data, addr = self.socket_instance.recvfrom(1024)
                    data = data.decode().strip()
                    print(data)
                except Exception as e:
                    data = quit
                    addr = None
                # 拿到心跳信息
                if data == @#!%%^SDF@:
                    self.clients.add(addr)
                    continue
                # 拿到数据, 如果是quit
                if data == quit:
                    if addr in self.clients:
                        self.clients.remove(addr)
                    # 这里continue的原因是,udp不需要与客户端建立连接,每次请求来了以后,可以直接拿到客户端发送的数据
                    # 不是break
                    continue
                self.clients.add(addr)
                threading.Thread(target=self.__send,args=(data, ), name=send).start()
        def __send(self, data):
            for addr in self.clients:
                self.socket_instance.sendto(Robby收到{}\n.format(data).encode(), addr)
        def stop(self):
            self.clients.clear()
            self.event.set()
            self.event.wait(3)
            self.socket_instance.close()
            print(UDP服务器停止)
            raise SystemExit(0)
    if __name__ == __main__:
        # 1: 启动服务器端
        chatServer = Server()
        # 2:用户可以输入quit暂停服务器
        while True:
            cmd = input(请输入命令: ).strip()
            chatServer.stop() if cmd == quit else print(可以输入quit暂停服务器端)

 

 

UDP客户端

 

    import threading
    import socket
    class Client:
        def __init__(self, ip=127.0.0.1, port=9000, interval=5):
            self.socket_instance = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
            self.addr = (ip, port)
            self.event = threading.Event()
            self.interval = interval
            self.__run()
        def __sendHeartBeat(self):
            while not self.event.wait(5):
                # 客户端发送的心跳包,服务器端不会回包
                self.socket_instance.sendto(@#!%%^SDF@.encode(), self.addr)
        def __recvfrom(self):
            while not self.event.is_set():
                try:
                    data, addr = self.socket_instance.recvfrom(1024)
                    print(addr)
                    print(data.decode())
                except Exception as e:
                    print(e)
        def __serverQuit(self):
            self.socket_instance.sendto(quit.encode(), self.addr)
        def send(self, data:str):
            self.socket_instance.sendto(data.encode(), self.addr)
        def __run(self):
            # 启动一个线程,发送心跳包
            threading.Thread(target=self.__sendHeartBeat, daemon=True).start()
            # 启动一个线程,接收数据
            threading.Thread(target=self.__recvfrom, ).start()
        def stop(self):
            self.__serverQuit()
            self.event.set()
            self.event.wait(3)
            self.socket_instance.close()
            print(UDP客户端停止)
            raise SystemExit(0)
    if __name__ == __main__:
        # 1:启动客户端
        client = Client()
        # 客户端可以像服务器端发送数据
        while True:
            cmd = input(请输入内容:).strip()
            client.stop() if cmd == quit else client.send(cmd)

 

 

 

1.TCP 和UDP的区别有哪些

  • TCP传输数据使用字节流的方式传输,而UDP是数据报传输;

  • TCP对网络条件要求高,而UDP更适合实时传输;

  • TCP编程可以保证传输的可靠性,UDP则不保证;

  • TCP会产生粘包现象,而UDP则容易丢包;

  • TCP使用listen方法和accpet方法,而UDP不需要;

  • TCP使用recv方法和send方法,而UDP使用recvfrom方法和sendto方法;

2.UDP 服务器端的实现

  • 创建 socket 对象;

  • 向socket 对象绑定服务器地址;

  • 进入与客户端交互数据的循环阶段;

  • 接收客户端发来的数据(包括 bytes 对象 data,以及客户端的 IP 地址和端口号 addr,其中 addr 为二元组 (host, port);

  • 打印接收信息,表示从地址为 addr 的客户端接收到数据);

  • 关闭;

3.UDP客户端的实现

  • 创建 socket 对象;

  • 初始化 UDP 服务器的地址;

  • 进入与服务器交互数据的循环阶段;

  • 等待用户输入数据;

  • 向服务器端发送接收数据;

  • 关闭套接字,不再向服务器发送数据;

 

44.socket编程(三)

原文:https://www.cnblogs.com/zhongguiyao/p/14874333.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!