zoukankan      html  css  js  c++  java
  • python网络编程:socket半连接池、UDP通讯模板

    本文目录:

    一、TCP半连接池原理

    二、UDP通讯

    三、UDP聊天

    四、UDP聊天2

    五、UDP会粘包吗

    六、UDP总结

    七、UDP与TCP对比

     

    一、TCP半连接池原理

    客户端

    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:continue
            client.send(data.encode("utf-8"))
            msg = client.recv(1024).decode("utf-8")
            print(msg)
    
    client.close()

    服务器

    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()
                break
    server.close()

    二、UDP通讯

    服务器

    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_addr = server.recvfrom(1024)
        print("收到来自%s: 说:%s" % (c_addr[0] ,msg.decode("utf-8")))
        # 发送数据到指定ip和端口
        server.sendto(msg.upper(),c_addr)

    客户端

    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_addr = server.recvfrom(1024)
        print("收到来自%s: 说:%s" % (c_addr[0] ,msg.decode("utf-8")))
        # 发送数据到指定ip和端口
        server.sendto(msg.upper(),c_addr)

    三、UDP聊天

    客户端1

    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"))

    客户端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"))

    服务器

    """
        群聊思路
            1.客户端先把数据交给服务器
            2.服务器先存储对方的地址
            3.把收到的数据给所有人都发一遍
    
    """
    
    
    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    server.bind(("127.0.0.1",8848))
    
    
    # 如果客户端与服务器在同一台计算机  并且有多个客户端  这些客户端ip都是相同的127.0.01
    
    clients = {}#定义个群聊客户字典
    
    while True:
        msg,addr = server.recvfrom(1024)
    
        # 存储对方的地址:
        clients[addr[1]] = addr
    
        print(msg.decode("utf-8"))
        # 循环发给所有人
        for c in clients:
            # 这个消息不用给发送方发回去
            # if c == addr[1]:
            #     continue
            server.sendto(msg,clients[c])

     

    四、UDP聊天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))

    服务器

    """
        群聊思路
            1.客户端先把数据交给服务器
            2.服务器先存储对方的地址
            3.把收到的数据给所有人都发一遍
    
    """
    
    
    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    server.bind(("127.0.0.1",8848))
    
    
    # 如果客户端与服务器在同一台计算机  并且有多个客户端  这些客户端ip都是相同的127.0.01
    
    clients = {}
    
    while True:
        msg,addr = server.recvfrom(1024)
    
        # 存储对方的地址:
        clients[addr[1]] = addr
    
        print(msg.decode("utf-8"))
        # 循环发给所有人
        for c in clients:
            # 这个消息不用给发送方发回去
            # if c == addr[1]:
            #     continue
            server.sendto(msg,clients[c])

    接收机

    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"))

     

    五、UDP会粘包吗

    1.UDP 不会粘包
    2.缓冲区大小要足够装数据包大小  建议不要超过512
    UDP的使用场景: 视频电话 语音电话  直播
    DNS  域名解析服务器

    六、UDP总结

    1.TCP模板代码
        半连接池的工作原理
        目前我们的程序是单线程 服务器要么处理通讯要么处理连接请求 无法同时进行
    2.TCP 和 UDP 发送数据时的流程 *****
        解释 为何TCP是可靠的 是因为发送数据后必须收到确认包
    3. UDP的模板代码 *****
        与TCP代码的区别
        不需要监听 不需要接收
        type参数为 SOCK_DGRAM
        UDP 可以同时处理多个客户端 是因为CPU处理速度快 给人感觉像是同时处理
     

    七、UDP与TCP对比

    """
        TCP  可靠的传输
            TCP传输数据前需要三次握手建立连接
        UDP  不可靠传输
            直接发送数据包  不关心对方是否接收成功
    """
  • 相关阅读:
    Java中RuntimeException和Exception的区别
    dubbo常见错误
    Spring3.x 版本和 JDK1.8 不兼容导致 java.lang.IllegalStateException: Failed to load ApplicationContext
    @Autowired与@Resource的区别
    阿里巴巴数据库连接池 druid配置详解
    HttpDns原理
    spring四种依赖注入方式
    JdbcTemplate
    springmvc常用注解标签详解
    访问spring接口一定要用.do么?
  • 原文地址:https://www.cnblogs.com/wuzhengzheng/p/10268546.html
Copyright © 2011-2022 走看看