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
原文地址:https://www.cnblogs.com/xuanxuanlove/p/9742703.html