zoukankan      html  css  js  c++  java
  • python学习笔记 day31 基于UDP的socket连接

    1. 简单版本---同一主机的不同进程之间通信

    # server.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',8080))
    
    msg,addr=sk.recvfrom(1024)  # 基于UDP的socket连接服务端只能先接收,而且使用recvfrom()得到元组,分别是客户端发来的消息以及客户端的地址
    print(msg.decode('utf-8'))
    sk.sendto(bytes('hello,我是服务端发来的消息'.encode('utf-8')),addr)  # UDP协议的socket 服务端给客户端发送消息时还需要带上客户端的地址
    sk.close()
    # client.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=('127.0.0.1',8080)  # 客户端需要指定所要请求连接的服务器
    sk.sendto(bytes('你好服务器,我是客户端发来的消息'.encode('utf-8')),id_port)
    msg,addr=sk.recvfrom(1024)  # 客户端收到服务器的消息以及服务器的地址(其实这里的addr也就是id_port)
    print(msg.decode('utf-8'))
    sk.close()

     

    2. 同一主机的两个不同进程之间的实时通信

    # server.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)  # 创建一个UDP的socket对象
    sk.bind(('127.0.0.1',8080))  # 绑定一个IP地址和端口号
    while True:
        msg,addr=sk.recvfrom(1024)  # 接收客户端发来的消息和客户端的地址
        print(msg.decode('utf-8'))
        info=input(">>>")
        sk.sendto(info.encode('utf-8'),addr)  # 给客户端发送消息时除了要写发送的消息还需要客户端的地址
    
    sk.close()
    # client.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=('127.0.0.1',8080)
    while True:
        info=input(">>>")
        sk.sendto(bytes(info.encode('utf-8')),id_port)
        msg,addr=sk.recvfrom(1024)
        print(msg.decode('utf-8'))
    sk.close()

    运行结果:

     

     3. 基于UDP实现QQ版尬聊

    之前基于TCP的长连接意思是在同一时间只能跟一个客户端聊天,但是当跟一个客户端的连接断开时,可以继续跟其他客户端建立连接,互相聊天;

    但是基于UDP的服务器可以和多个客户端同时聊天;

    # server.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',8080))
    while True:
        msg,addr=sk.recvfrom(1024)
        print(addr)  # 可以查看是哪一个客户端(recvfrom()不仅得到客户端发来的消息,还有客户端的地址)
        print(msg.decode('utf-8'))
        info=input(">>>")
        sk.sendto(bytes(info.encode('utf-8')),addr)
    sk.close()
    # client.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=('127.0.0.1',8080)
    while True:
        info=input(">>>")
        info = ("33[44m来自客户端1的消息:%s33[0m" %info).encode('utf-8')  # 客户端给服务器发送消息时加上一些附属信息以及颜色,便于多个客户端之间的区分
        sk.sendto(info,id_port)
        msg,addr=sk.recvfrom(1024)
        print(msg.decode('utf-8'))
    
    sk.close()
    # client2.py
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=('127.0.0.1',8080)
    
    while True:
        info=input(">>>")
        info=("33[35m来自客户端2号的消息:%s33[0m"%info).encode('utf-8')
        sk.sendto(info,id_port)
        msg,addr=sk.recvfrom(1024)
        print(msg.decode('utf-8'))
    sk.close()

     运行结果:

     

     4.作业

    server端提供服务,接受信息(客户端发来的时间的格式),将时间转化为接收到的格式再发给客户端;

    client端,给服务端发送自己想要的世间的格式,然后接收到服务端处理过的时间的格式;

    # server.py
    import socket
    import time
    import pickle
    
    sk = socket.socket(type=socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1', 8080))
    while True:
        msg, addr = sk.recvfrom(1024)
        msg=msg.decode("utf-8")
        print("接收到%s发来的格式为:%s" % (addr, msg))
        info = time.strftime(msg, time.localtime())  # 将接收到的格式转化为格式化时间
        info_str=pickle.dumps(info)  # 把格式化时间转化为字符串,以便进行传输
        sk.sendto(info_str, addr)
    
    sk.close()
    # client1.py
    import time
    import pickle
    import socket
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=("127.0.0.1",8080)
    while True:
        format=input(">>>")
        sk.sendto(format.encode('utf-8'),id_port)
        msg_str,addr=sk.recvfrom(1024)
        msg=pickle.loads(msg_str)
        print(msg)
    sk.close()
    # client2.py
    import socket
    import time
    import pickle
    
    sk=socket.socket(type=socket.SOCK_DGRAM)
    id_port=('127.0.0.1',8080)
    
    while True:
        format=input(">>>")
        sk.sendto(bytes(format.encode('utf-8')),id_port)
        msg_str,addr=sk.recvfrom(1024)
        msg=pickle.loads(msg_str)
        print(msg)
    sk.close()

    运行结果:

     

    这里需要注意的就是 网络传输都需要转化为bytes类型的;而且时间格式这种非字符串类型的需要借助pickle序列化为字符串类型,然后再loads回原来的格式;

    关于encode 和 decode 前者是针对中文字符做的处理,先编码 然后转为bytes类型(如果本身是bytes类型就不要使用encode),后者是对bytes类型的数据转为可以显示的格式(如果本身是非bytesl类型则不可以使用)

    talk is cheap,show me the code
  • 相关阅读:
    7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)
    Mybatis-利用resultMap 输出复杂pojo
    1.2MyBatis介绍
    1Mybatis入门--1.1单独使用jdbc编程问题总结
    AJAX的来龙去脉(由来)-如何被封装出来的--ajax发送异步请求(四步操作)
    人人权限 添加一张表查询出来
    salesforce lightning零基础学习(九) Aura Js 浅谈二: Event篇
    salesforce lightning零基础学习(八) Aura Js 浅谈一: Component篇
    salesforce lightning零基础学习(七) 列表展示数据时两种自定义编辑页面
    salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9742703.html
Copyright © 2011-2022 走看看