zoukankan      html  css  js  c++  java
  • UDP协议(数据报协议)

    一、UDP协议

    没有双向通道,传输数据不可靠,可能出现丢包现象

    通信速度比较快,发送的数据不会在内存中保留

    1、特性:

    ①UDP协议不存在粘包问题

    ②客户端可以发空,自带数据报头

    ③udp可以实现并发的效果

    ④服务端不存在,也不影响客户端朝服务端发送数据

    2、分析:

    ①UDP叫数据报协议,意味着发消息都带有数据报头

    ②UDP的server不需要就行监听也不需要建立连接

    ③启动服务之后只能被动的等待客户端发消息过来,

      客户端发消息的时候,带上服务端的地址 client.sendto(b'hello', server_addr)

      服务端发消息的时候,带上客户端的地址 server.sendto(msg.upper(), addr)

    3、TCP和UDP

    TCP:类似于打电话,要确定服务端收到

    UDP:类似于发短信,不考虑服务端是否收到

    4、UDP简单使用

    ①服务端

    import socket
    
    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 8080))
    while True:
        msg, addr = server.recvfrom(1024)  # 接收到客户端信息
        server.sendto(msg.upper(), addr)   # 处理信息发送给客户端
        print(msg)
    
    server.close()

     ②客户端

    import socket
    
    client = socket.socket(type=socket.SOCK_DGRAM)
    server_addr = ('127.0.0.1', 8080)  # 服务端地址,通常写在配置文件中
    
    while True:
        msg = input('>>>:').strip()
        client.sendto(msg.encode('utf-8'), server_addr)
        msg, addr = client.recvfrom(1024)
        print(msg.decode('utf-8'))
    
    client.close()

    先运行服务端,再运行客户端,客户端中输入信息,查看打印结果:

    服务端:

     客户端:

    5、UDP不存在粘包现象

    UDP不存在粘包现象,是由于UDP发送的时候,没有经过Negal算法优化,不会将多个小包合并一次发送出去。另外,在UDP协议的接收端,采用了链式结构来记录每一个到达的UDP包,这样接收端应用程序一次recv只能从socket接收缓冲区中读出一个数据包。也就是说,发送端send了几次,接收端必须recv几次(无论recv时指定了多大的缓冲区)。

    ①服务端

    import socket
    
    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1', 8080))
    
    # 验证udp是否粘包:不粘包
    msg, addr = server.recvfrom(1024)
    print(msg)    # b'baby~'
    msg1, addr1 = server.recvfrom(1024)
    print(msg1)   # b'baby~'
    msg2, addr2 = server.recvfrom(1024)
    print(msg2)   # b'baby~'

    ②客户端

    import socket
    
    client = socket.socket(type=socket.SOCK_DGRAM)
    server_addr = ('127.0.0.1', 8080)  # 服务端地址,通常写在配置文件中
    
    
    # 验证udp是否粘包:不粘包
    client.sendto(b'baby~', server_addr)
    client.sendto(b'baby~', server_addr)
    client.sendto(b'baby~', server_addr)

    二、基于UDP实现简易版本的QQ

     ①服务端

    import socket
    
    server = socket.socket(type=socket.SOCK_DGRAM)
    server.bind(('127.0.0.1',8080))
    
    while True:
        msg,addr = server.recvfrom(1024)
        print(msg.decode('utf-8'))
        data = input('>>>:').encode('utf-8')
        server.sendto(data,addr)

    ②客户端

    import socket
    
    client = socket.socket(type=socket.SOCK_DGRAM)
    server_addr = ('127.0.0.1',8080)
    
    while True:
        msg = input('>>>:')
        msg = '客户端1的消息:%s'%msg
        client.sendto(msg.encode('utf-8'),server_addr)
        data,addr = client.recvfrom(1024)
        print(data)

    三、socketserver模块

     1、能够实现并发效果
       并发:看起来像同时运行就能称之位并发
     2、udp在使用的时候,多个客户端要有一些io操作,不然容易卡死

  • 相关阅读:
    北京
    构建JDBC的基本代码
    JavaScript:制作简易计算器要注意的事项!
    JavaScript学习笔记-创建对象之设计模式
    .NET开源工作流RoadFlow-流程设计-流程步骤设置-事件设置
    .NET开源工作流RoadFlow-流程设计-流程步骤设置-数据设置
    .NET开源工作流RoadFlow-流程设计-流程步骤设置-按钮设置
    .NET开源工作流RoadFlow-流程设计-流程步骤设置-策略设置
    .NET开源工作流RoadFlow-流程设计-流程步骤设置-基本设置
    .NET开源工作流RoadFlow-流程设计-流程属性设置
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/15444292.html
Copyright © 2011-2022 走看看