• UDP协议 并发编程


    一.TCP半连接池原理

      半连接池的工作原理

      目前我们的程序是单线程  服务器要么处理通讯要么处理连接请求 无法同时进行

    #服务器
    
    import socket
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(("127.0.0.1",9999))
    # 不是罪大连接数
    server.listen(5)
    while True:
        c,addr = server.accept
        while True:
            try:
                msg = c.recv(1024).decode("utf-8")
                if not msg:
                    c.close()
                    break
                c.send(msg.upper().encode("utf-8"))
            except BaseException:
                print("客户端异常断开")
                c.close()
    server.close()
    
    
    #用户端
    
    import socket
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(("127.0.0.1",9999))
    while True:
        data = input(">>>:")
        if not data:coninue
        client.send(data.encode("utf-8")
        print(msg)
    client.close()

    二.TCP 和 UDP 发送数据是的流程

      解释 为何TCP是可靠的 是因为发送数据后必须受到确认包

    #服务器
    
    import socket
    #创建socket对象 指定type参数为socket.SOCK_DGRAM表示使用UDP协议
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#datagram数据报的意思
    # 绑定ip和端口
    server.bind(("127.0.0.1",8888))
    while True:
        # 接受数据 返回一个元祖  数据和  发送方的地址
        msg,c_adde = server.recvfrom(1024)
        print("收到来自%s: 说:%s"%(c_addr[0],msg.decode("utf-8")))
        # 发送数据到指定ip和端口
        server.sendto(msg.upper(),c_addr)
    
    
    #客户端
    import socket
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        msg = input(">>>:")
        client.sendto(msg.encode("utf-8"),("127.0.0.1",8888))
        print(data.decode("utf-8")

    三.UDP聊天

      与TCP代码的区别

      不需要监听 不需要接收

      type参数为 SOCK_DGRAM

      UDP 可以同时处理多个客户端 是因为CPU处理速度快 给人感觉像同时处理

      群聊

        1.客户端先把数据交给服务器

        2.服务器先存储对方的地址

        3.把收到的数据给所有人都发一遍

    #服务器
    
    import socket
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    server.bind(("127.0.0.1",8848))
    
    #如果客户端与服务器同一台计算机  并且有多个客户端  这些客户端ip都是相同127.0.0.1
    clients = {}
    while True:
        msg,addr = server.recvfrom(1024)
        # 存储对方的地址:
        clients[addr[1]] = addr
        print(msg.decode("utf-8"))
        #循环发给所有人
        for c in clients:
            server.sendto(msg,clients[c])
    
    #客户端1
    import socket
    c = coket.c=soket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        msg= input(">>>:")
        c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))
        msg,addr = c.recvfrom(1024)
        print(msg.decode("utf-8"))
    #客户端2
    import socket
    c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        msg = input(">>>:"
        c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))
        msg,addr = c.recvfrom(1024)
        print(msg.decode("utf-8"))

    UDP聊天2

    #服务器
    import socket
    server = socket.socket(socket.AF_INET,sccket.SOCK_DGRAM)
    server.bind(("127.0.0.1",8848))
    clients={}
    while True:
        msg,addr = server.recvfrom(1024)
        clients[addr[1]] = addr
    
        print(msg.decode("utf-8"))
        for c in clients:
            server.sendto(msg,clients[c])
    
    #发送机
    import socket
    c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while True:
        msg = input(">>>:")
        c.sendto(msg.encode("utf-8"),("127.0.0.1",8848)
    
    #接收机
    import socket
    c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    #先随便发一条消息给服务器  让服务指导自己的地址
    c.sendto("register".encode("utf-8"),("127.0.0.1",8848))
    while True:
        msg,addr = c.recvfrom(1024)
        print(msg.decode("utf-8"))
        

    6.UDP会粘包么?

    #服务器
    
    import socket
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    server.bind(("127.0.0.1",8888))
    while True:
        msg,c_addr = server.recvfrom(512)
        
        print("收到自己%: 说:%s"%(c_addr[0],msg.decode("utf-8")))
        server.sendto(msg.upper(),c_addr)
    
    #客户端
    import socket
    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    client.sendto("10".encode("utf-8"),("127.0.0.1"8888))
    client.sendto("22".encode("utf-8"),("127.0.0.1"8888))
    client.sendto("32".encode("utf-8"),("127.0.0.1"8888))
    client.sendto("43".encode("utf-8"),("127.0.0.1"8888))

    结论:

      1.UDP 不粘包

      2.缓冲区大小要足够装数据包大小 建议不要超过512

    UDP的使用场景: 视频电话 语音电话  直播

    DNS   域名解析服务器

    做一个时间服务器 使用UDP协议  客户端请求服务器获取当前时间

    #服务端
    import socket
    import time
    # 创建socket对象  指定type参数为socket.SOCK_DGRAM 表示使用UDP协议
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # datagram数据报的意思
    # 绑定ip和端口
    server.bind(("127.0.0.1",8889))
    
    while True:
        # 接收数据 返回一个元祖  数据和 发送方的地址
        msg,c_addr = server.recvfrom(1024)
        msg=time.strftime("%Y-%m-%d %X").encode("utf-8")
        print("%s 收到来自%s: 说:%s" % (time.strftime("%Y-%m-%d %X"),c_addr[0] ,msg.decode("utf-8")))
        print(type(msg))
        # 发送数据到指定ip和端口
        server.sendto(msg.upper(),c_addr)
    
    #用户端
    import socket
    
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # datagram数据报的意思
    
    while True:
        msg = input(">>>:")
        client.sendto(msg.encode("utf-8"),("127.0.0.1",8889))
        data,addr = client.recvfrom(1024)
        print(data.decode("utf-8"))
  • 相关阅读:
    求解大于或等于某个4字节正整数的最小2次幂
    C++17 std::optional
    C++主动调用析构函数
    std::raise()
    C++ std::integral_constant
    C++ range-v3库的安装与测试[Utunbu 18.04]
    python将YUV420P文件转PNG图片格式
    python将两张图片横向或者纵向合成一张
    folly库之Benchmark.h
    Facebook的folly库在Utunbu上的编译
  • 原文地址:https://www.cnblogs.com/gongcheng-/p/9916617.html
Copyright © 2020-2023  润新知