<s id="mvh2b"><strike id="mvh2b"><u id="mvh2b"></u></strike></s>
    1. <rp id="mvh2b"></rp>

      当前位置:首页 > IT教程

      UDP编程

      时间:2019-11-23 03:35:01来源:金橙教程网 作者:admin8 阅读:52次 [手机版]
       

      udp编程

      测试命令
      #windows查找UDP是否启动端口
      > netstat -anp udp | find "9999"
      > netstat -anbp udp | findstr 9999
      

      UDP服务端编程

      在这里插入图片描述

      • 创建socket对象。socket.SOCK_DGRAM

      • 绑定IP和Port,bind()方法

      • 传输数据

        • 接收数据,socket.recvfROM(bufsize[,flags]),获得一个二元组(String,address)
        • 发送数据,socket.sendto(string,address)发给某地址某信息
      • 释放资源

      import socket
      Server=socket.socket(type=socket.SOCK_DGRAM)
      server.bind(('172.22.141.176',9999))
      DATa=server.recv(1024)
      print(data)
      data=server.recvfrom(1024)
      print(data)
      server.sendto(b'110110',('172.22.141.176',10000))
      server.close()
      

      在这里插入图片描述

      在这里插入图片描述

      UDP客户端编程流程

      • 创建socket对象,socket.SOCK_DGRAM
      • 发送数据,socket.sendto(string,address)发送给某地址某信息
      • 接收数据,socket.recvfrom(bufsize[,flags]),获得一个二元组(string,address)
      • 释放资源
      import socket
      client=socket.socket(type=socket.SOCK_DGRAM)
      raddr=('172.22.141.176',11111)
      
      client.connect(raddr)
      client.sendto(b'1008611',raddr)
      client.send(b'132132323')
      data=client.recvfrom(1024)
      print(data)
      data=client.recv(1024)
      print(data)
      
      client.close()
      

      在这里插入图片描述

      注意:UDP是无连接协议,所以可以只有任何一端,例如客户端数据发往服务端,服务端存在与否无所谓。

      UDP编程bind、connect、send、sendto、recv、recvfrom方法使用

      UDP的socket对象创建后,是没有占用本地地址和端口的。

      方法 说明
      bind方法 可以指定本地地址和端口laddr,会立即占用
      connect方法 可以立即占用本地地址和端口laddr,填充远端地址和端口raddr
      sendto方法 可以立即占用本地地址和端口laddr,并发数据发往指定远端,只有有了本地绑定端口,sendto就可以向任何远端发送数据
      send方法 需要和connect方法配合,可以使用已经从本地端口把数据发往raddr指定的远端
      recv方法 要求一定要在占用了本地端口后,返回接收的数据
      recvfrom方法 要求一定要占用本地端口后,返回接收的数据和对端地址的二元组
      • UDP群聊服务端
      import socket
      import threading
      class ChatUdpServer:
          def __init__(self,ip='0.0.0.0',port=11112):
              self.Ipaddr=ip,port
              self.sock=socket.socket(type=socket.SOCK_DGRAM)
              self.clients=set()
              self.event=threading.Event()
              self.lock=threading.Lock()
          def start(self):
              self.sock.bind(self.ipaddr)
              threading.Thread(target=self.recv).start()
          def recv(self):
              while not self.event.is_set():
                  try:
                      data,other=self.sock.recvfrom(1024)
                      print(data)
                      if data==b'quit':
                          with self.lock:
                              self.clients.remove(other)
                          continue
                      with self.lock:
                          self.clients.add(other)
                      with self.lock:
                          for i in self.clients:
                              self.sock.sendto(data,i)
                  except:
                      print('ERROR')
          def stop(self):
              self.event.set()
              self.clients.clear()
              try:
                  self.sock.close()
              except:
                  print('over')
              finally:
                  print('over')
      chat=ChatUdpServer()
      chat.start()
      while True:
          cmd=input(">>>").strip()
          if cmd=='quit':
              chat.stop()
              break
          print(threading.enumerate())
      
      • UDP客户端
      import socket
      import threading
      import time
      class ChatUdpClient:
          def __init__(self,ip='172.22.141.176',port=11113):
              self.sock=socket.socket(type=socket.SOCK_DGRAM)
              self.ipadd=ip,port
              self.event=threading.Event()
              self.lock=threading.Lock()
          def start(self):
              self.sock.connect(self.ipadd)
              threading.Thread(target=self.send).start()
              threading.Thread(target=self.recv).start()
          def send(self):
              while not self.event.is_set():
                  with self.lock:
                      data=input("你说话呀:").strip().encode()
                      self.sock.sendto(data,self.ipadd)
          def recv(self):
              while not self.event.is_set():
                  message=self.sock.recvfrom(1024)
                  print(message)
          def stop(self):
              self.event.set()
              self.sock.close()
      chat=ChatUdpClient()
      chat.start()
      while True:
          time.sleep(10)
          cmd=input('>>>').strip()
          if cmd=='quit':
              chat.stop()
          print(threading.enumerate())
      

      上面的例子并不完善,如果客户端断开了,服务端不知道,每一个服务端还需要对所有客户端发送数据,包括已经断开的客户端

      服务端代码改进

      增加心跳机制heartbeat机制或ack机制,这些机制同样用在TCP通信的时候。

      心跳,就是一端定时发往另一端的信息。

      ack即相应,一端收到另一端的信息后返回的确认信息。

      心跳机制:

      1、一般来说是客户端定时发往服务端的,服务端并不需要ack回复客户端,只需要记录该客户端活着就行了。

      2、如果是服务端定时发往客户端的,一般需要客户端ack相应来表示活着,如果没有收到ack的客户端,服务端移除其信息,这种实现较为复杂,用的较少

      3、双向发心跳

      import socket
      import threading
      import datetime
      class ChatUdpServer:
          def __init__(self,ip='172.22.141.176',port=11113,interval=10):
              self.ipaddr=ip,port
              self.sock=socket.socket(type=socket.SOCK_DGRAM)
              self.clients=dict()
              self.event=threading.Event()
              self.lock=threading.Lock()
              self.interval=interval
          def start(self):
              self.sock.bind(self.ipaddr)
              threading.Thread(target=self.recv).start()
          def recv(self):
              while not self.event.is_set():
                  start = datetime.datetime.now().timestamp()
                  try:
                      data,other=self.sock.recvfrom(1024)
                      if data.strip()==b'^bbb^':
                          self.clients[other]=start
                          continue
                      elif data==b'quit':
                          with self.lock:
                              self.clients.pop(other)
                          continue
                      with self.lock:
                          self.clients[other]=start
                      with self.lock:
                          fail=set()
                          print(fail)
                          for i,k in self.clients.items():
                              print(self.clients)
                              print(k)
                              print(start)
                              if start-k>self.interval:
                                  fail.add(i)
                              else:
                                  self.sock.sendto(data,i)
                          for c in  fail:
                              self.clients.pop(c)
                  except:
                      print('error')
          def stop(self):
              self.event.set()
              self.clients.clear()
              try:
                  self.sock.close()
              except:
                  print('over')
              finally:
                  print('over')
      chat=ChatUdpServer()
      chat.start()
      while True:
          cmd=input(">>>").strip()
          if cmd=='quit':
              chat.stop()
              break
          print(threading.enumerate())
      
      • 客户端增加心跳机制
      import socket
      import threading
      import time
      class ChatUdpClient:
          def __init__(self,ip='172.22.141.176',port=11113):
              self.sock=socket.socket(type=socket.SOCK_DGRAM)
              self.ipadd=ip,port
              self.event=threading.Event()
              self.lock=threading.Lock()
          def start(self):
              self.sock.connect(self.ipadd)
              threading.Thread(target=self.send).start()
              threading.Thread(target=self.recv).start()
              threading.Thread(target=self.heartbeat).start()
          def heartbeat(self):
              while not self.event.wait(5):
                  self.sock.send(b'^^bb^^')
          def send(self):
              while not self.event.is_set():
                  with self.lock:
                      data=input("你说话呀:").strip().encode()
                      self.sock.sendto(data,self.ipadd)
          def recv(self):
              while not self.event.is_set():
                  message=self.sock.recvfrom(1024)
                  print(message)
          def stop(self):
              self.event.set()
              self.sock.close()
      chat=ChatUdpClient()
      chat.start()
      while True:
          time.sleep(10)
          cmd=input('>>>').strip()
          if cmd=='quit':
              chat.stop()
          print(threading.enumerate())
      

      相关阅读

      程序设计模式————编程模式

      设计模式的分类 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式

      UDP数据包解析

      在如何封装一个数据包上&#xff0c;是一个非常细致的问题&#xff0c;而利用UDP协议来封装的话&#xff0c;是比较简单&#xff0c;让我们一步步

      C#高级编程(一)

      1.字符串和正则表达式1,CompareTo()方法&#xff0c;比较字符串的内容2,Replace()用另一个字符或者字符串替换字符串中给定的字符或者

      UDP协议

      1 UDP协议 1.1 UDP认识 UDP是一种简单的面向数据报、无

      高手教你如何从零开始学游戏编程

      开发游戏可能是学习编程的理由中最吸引人的一条了。但如何从零开始入门&#xff0c;达到能够开发游戏的编程水平&#xff0c;是困扰无数勇

      分享到:

      IT相关

      程序相关

      推荐文章

      热门文章

      东北老女人嫖老头视频_无遮挡H肉动漫视频在线观看_欧美牲交a欧美牲交aⅴ另类_狼人乱码无限2021芒果