• Python UDP实例


    UDP通信过程

    udp 不需要经过3次握手和4次挥手,不需要提前建立连接,直接发数据就行。

    server端

    import socket
    BUFSIZE = 1024
    ip_port = ('127.0.0.1', 9999)
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # udp协议
    server.bind(ip_port)
    while True:
        data,client_addr = server.recvfrom(BUFSIZE)
        print('server收到的数据', data)
    
        server.sendto(data.upper(),client_addr)
    
    server.close()
    

    client端

    import socket
    BUFSIZE = 1024
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        msg = input(">> ").strip()
        ip_port = ('127.0.0.1', 9999)
        client.sendto(msg.encode('utf-8'),ip_port)
    
        data,server_addr = client.recvfrom(BUFSIZE)
        print('客户端recvfrom ',data,server_addr)
    
    client.close()
    

     输出结果

    server:
    
    server收到的数据 b'hello'
    server收到的数据 b'world'
    
    
    client:
    >> hello
    客户端recvfrom  b'HELLO' ('127.0.0.1', 9999)
    >> world
    客户端recvfrom  b'WORLD' ('127.0.0.1', 9999)
    >> 
    

      

    粘包分析

    第一种:

    server

    from socket import *
    import time
    server=socket(AF_INET,SOCK_DGRAM)
    server.bind(('127.0.0.1',8880))
    
    
    res1=server.recvfrom(10) #b'hello'
    print('第一次:',res1)
    
    res2=server.recvfrom(1024) #b'world'
    print('第二次:',res2)
    
    
    server.close()
    

      

    client

    from socket import *
    import time
    client = socket(AF_INET, SOCK_DGRAM)
    
    
    client.sendto(b'hello',('127.0.0.1',8880))
    
    client.sendto(b'world',('127.0.0.1',8880))
    
    client.close()
    

    服务端结果:没有产生粘包

    第一次: (b'hello', ('127.0.0.1', 63959))
    第二次: (b'world', ('127.0.0.1', 63959))

    第二种:

    server:
    
    
    from socket import *
    import time
    server=socket(AF_INET,SOCK_DGRAM)
    server.bind(('127.0.0.1',8880))
    
    
    res1=server.recvfrom(2) #b'he'
    print('第一次:',res1)
    time.sleep(6)
    res2=server.recvfrom(1024) #b'world'
    print('第二次:',res2)
    
    
    server.close()
    
    
    client:
    
    from socket import *
    import time
    client = socket(AF_INET, SOCK_DGRAM)
    
    
    client.sendto(b'hello',('127.0.0.1',8880))
    time.sleep(5)
    client.sendto(b'world',('127.0.0.1',8880))
    
    client.close()  

     输出结果

    windows直接报错:
    Traceback (most recent call last):
    /路飞/第三模块/第二章网络编程/06 基于udp协议的套接字/服务端.py", line 24, in <module>
        res1=server.recvfrom(2) #b'he'
    OSError: [WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。
    
    
    mac或linux:
    直接丢包,只收到b'he',后面的llo不会收到
    

      

    TCP VS UDP

    tcp基于链接通信

    • 基于链接,则需要listen(backlog),指定连接池的大小
    • 基于链接,必须先运行的服务端,然后客户端发起链接请求
    • 对于mac系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端在收消息后加上if判断,空消息就break掉通信循环)
    • 对于windows/linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端通信循环内加异常处理,捕捉到异常后就break掉通讯循环)

    udp无链接

    • 无链接,因而无需listen(backlog),更加没有什么连接池之说了
    • 无链接,udp的sendinto不用管是否有一个正在运行的服务端,可以己端一个劲的发消息,只不过数据丢失
    • recvfrom收的数据小于sendinto发送的数据时,在mac和linux系统上数据直接丢失,在windows系统上发送的比接收的大直接报错
    • 只有sendinto发送数据没有recvfrom收数据,数据丢失

     

      

  • 相关阅读:
    装黑苹果遇到的术语
    关于Android方法数量限制的问题
    使用LeakCanary遇到的问题 就是不弹出来
    Android内存泄露自动检测神器LeakCanary
    Android开发常见的Activity中内存泄漏及解决办法
    LeakCanary 中文使用说明
    LeakCanary: 让内存泄露无所遁形
    LeakCanary——直白的展现Android中的内存泄露
    【腾讯Bugly干货分享】Android内存优化总结&实践
    Java基础--定时任务Timer
  • 原文地址:https://www.cnblogs.com/xiao-apple36/p/9279108.html
Copyright © 2020-2023  润新知