客户端
import socket client = socket.socket(type=socket.SOCK_DGRAM) # UDP 不需要建立连接(client.connect(('127.0.0.1', 8080))) server_addr = ('127.0.0.1', 8080) # UDP sendto发消息时需要一个服务器的地址及端口号 while True: msg = input("Please input your msg:").strip() client.sendto(msg.encode('utf-8'), server_addr) # 向服务器发送数据,要附带服务器端地址及端口(基于网络传输的数据都必须是二进制的) data, msg_from_server_addr = client.recvfrom(1024) # 收到消息,且得到地址 print("服务端发来的数据:", data.decode('utf-8')) print("服务器端的ip及端口", msg_from_server_addr) # 窗口1 # Please input your msg:hi # 服务端发来的数据: o hi # 服务器端的ip及端口 ('127.0.0.1', 8080) # Please input your msg: # 窗口2 # Please input your msg:hihihi # 服务端发来的数据: xxixixi # 服务器端的ip及端口 ('127.0.0.1', 8080) # Please input your msg: # 窗口3 # Please input your msg:aha e # # 服务端发来的数据: emmm? # 服务器端的ip及端口 ('127.0.0.1', 8080) # Please input your msg:服务端发来的数据: adsa # 服务器端的ip及端口 ('127.0.0.1', 8080) # Please input your msg: TCP与UDP之间的区别UDP 允许发空数据,不会有影响
UDP 直接启动客户端未启动服务端不会报错
UDP 不会有粘包问题(自带报头)
UDP 支持并发
服务端
import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1', 8080)) while True: data, addr = server.recvfrom(1024) print(data.decode('utf-8')) server.sendto(data.upper(), addr)客户端
import socket client = socket.socket(type=socket.SOCK_DGRAM) while True: msg = input(">>>:") # ------------------------------------------- # 1.UDP 允许发空数据,不会有影响 # ------------------------------------------- # UDP自带报头,就算数据为空,另一端也能处理 client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) # 第二参数,目标服务器地址 # ------------------------------------------- # 2.UDP 直接启动客户端未启动服务端不会报错 # 发数据找不到服务端也还是会报错 # ------------------------------------------- # 下面两行代码直接注释掉,服务端没启动,都不会报错,只管给服务器发(收没收到不管) # data, server_addr = client.recvfrom(1024) # print(data) # ------------------------------------------- # 3.UDP 不会有粘包问题(自带报头) # ------------------------------------------- # client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) # client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) # client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080)) # # server.sendto(data.upper(), addr) # server.sendto(data.upper(), addr) # server.sendto(data.upper(), addr) # ------------------------------------------- # 4.UDP 支持并发 # TCP是保持连接,而UDP不需要保持连接 # 与一个客户端断开连接才会和下一个客户端建立连接 # ------------------------------------------- 简易版的QQ服务器端
import socket server = socket.socket(type=socket.SOCK_DGRAM) server.bind(('127.0.0.1', 8080)) while True: data, client_addr = server.recvfrom(1024) print(data.decode('utf-8')) msg = input(">>>:").strip() server.sendto(msg.encode('utf-8'), client_addr) # 来自star3的消息:helo # >>>:hi # 来自star2的消息:aha # >>>:haa # 来自star的消息:hello world # >>>:ha # 来自star2的消息:jason nnn # >>>:jj客户端1、2、3共用同一份代码
import socket client = socket.socket(type=socket.SOCK_DGRAM) username = 'star' server_address = ('127.0.0.1', 8080) # 指定一个发消息的目标服务器 while True: msg = input(">>>:").strip() msg = f'来自{username}的消息:{msg}' # 是哪个用户名发出的数据不应该由这里传过去,用户可以随便改,实际意义不大 ''' user_dict = { "username1": (ip1 + port1), "username2": (ip2 + port2), "username3": (ip3 + port3), } # 可以在每个端都存这样一个对照表,根据ip与port就可以知道用户名了 ''' client.sendto(msg.encode('utf-8'), server_address) data, server_addr = client.recvfrom(1024) # server_addr 收到消息的服务端地址 print(data.decode('utf-8')) # 各个窗口的控制台输入与输出 # >>>:helo # hi # >>>: # >>>:aha # haa # >>>:jason nnn # jj # >>>: # >>>:hello world # ha # >>>: 概念科普并发
看起来像同时运行(直接启动多个UDP客户端)(默认的UDP程序多开就是这个效果)
并行
真正意义上的同时运行
socketserver模块科普是给服务端用的(客户端还是用socket模块),可以保持连接
TCP模拟UDP实现并发