zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python udp

Python UDP
2023-09-27 14:25:49 时间

目录

概述

下载网络调试助手

发送任意类型数据

03-循环发送数据

04-带有退出功能的循环发送

05-绑定端口用来接收数据

06-解析出接收到的数据

循环接收并显示

08-先绑定端口然后在循环发送

应用:udp聊天器



概述

 

TCP 是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对
TCP, UDP 则是面向无连接的协议。
使用 UDP 协议时,不需要建立连接,只需要知道对方的 IP 地址和端口
号,就可以直接发数据包。但是,能不能到达就不知道了。
虽然用 UDP 传输数据不可靠,但它的优点是和 TCP 比,速度快,对于
不要求可靠到达的数据,就可以使用 UDP 协议。
 

创建 Socket 时, SOCK_DGRAM 指定了这个 Socket 的类型是 UDP。绑定端
口和 TCP 一样,但是不需要调用 listen()方法,而是直接接收来自任何
客户端的数据

 

UDP 的使用与 TCP 类似,但是不需要建立连接。此外,服务器绑定 UDP
端口和 TCP 端口互不冲突,也就是说, UDP 的 9999 端口与 TCP 的 9999
端口可以各自绑定。
 

updserver.py

'''
UDP

TCP是建立可靠连接,并且通信双方都可以以流的形式发送数据。
相对TCP,UDP则是面向无连接的协议。
'''
'''
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。
但是,能不能到达就不知道了。
'''
'''
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
'''
'''
和TCP类似,使用UDP的通信双方也分为客户端和服务器。
'''
import socket

# 服务器首先需要绑定端口:
# 创建Socket时,SOCK_DGRAM指定了这个Socket的类型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1',8180))

# 绑定端口和TCP一样
# 但是不需要调用listen()方法,而是直接接收来自任何客户端的数据:
print('Bind UDP on 8180...')

while True:
    # 接收数据:
    # recvfrom()方法返回数据和客户端的地址与端口
    data,addr = s.recvfrom(1024)
    print('Received from %s:%s' % addr)
    # 这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
    tt = bytes('Hello,%s!' % data, encoding = "utf-8") 
    print("传入:",tt) 
    s.sendto(tt,addr)

updclient.py

'''
客户端使用UDP时,首先仍然创建基于UDP的Socket


然后,不需要调用connect(),直接通过sendto()给服务器发数据:
'''
import socket

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)


for data in [b'Jue',b'asd',b'rer']:
    s.sendto(data,('127.0.0.1',8180))
    print(s.recv(1024).decode('utf-8'))
s.close()

下载网络调试助手

 


import socket


def main():
	udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	str = b"The reading of all good books is like a conversation with the finest minds of past centuries"
	# trans = b"读好书,如同与先哲们交谈"
	udp_socket.sendto(str, ("192.168.19.10", 8080))
	# udp_socket.sendto(trans, ("192.168.19.10", 8080))

	print("run-------------")

	udp_socket.close()
	# 不


if __name__ == '__main__':
	main()
import socket

def main():
    # 创建一个udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 可以使用套接字收发数据
    # udp_socket.sendto("hahahah", 对方的ip以及port)
    udp_socket.sendto(b"hahahah------1----", ("192.168.33.53", 8080))

    # 关闭套接字
    udp_socket.close()
	

if __name__ == "__main__":
    main()

如果IP不在同一个段内,那是因为有虚拟网卡,把虚拟网上关闭就好了, ET***的禁了。

 

发送任意类型数据

import socket

def main():
    # 创建一个udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 从键盘获取数据
    send_data = input("请输入要发送的数据:")

    # 可以使用套接字收发数据
    # udp_socket.sendto("hahahah", 对方的ip以及port)
    # udp_socket.sendto(b"hahahah------1----", ("192.168.33.53", 8080))
    udp_socket.sendto(send_data.encode("utf-8"), ("192.168.33.53", 8080))


    # 关闭套接字
    udp_socket.close()
	

if __name__ == "__main__":
    main()

03-循环发送数据

import socket

def main():
    # 创建一个udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    while True:

        # 从键盘获取数据
        send_data = input("请输入要发送的数据:")

        # 可以使用套接字收发数据
        # udp_socket.sendto("hahahah", 对方的ip以及port)
        # udp_socket.sendto(b"hahahah------1----", ("192.168.33.53", 8080))
        udp_socket.sendto(send_data.encode("utf-8"), ("192.168.33.53", 8080))


    # 关闭套接字
    udp_socket.close()
	

if __name__ == "__main__":
    main()

 

04-带有退出功能的循环发送

import socket

def main():
    # 创建一个udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    while True:

        # 从键盘获取数据
        send_data = input("请输入要发送的数据:")

        # 如果输入的数据是exit,那么就退出程序
        if send_data == "exit":
            break

        # 可以使用套接字收发数据
        # udp_socket.sendto("hahahah", 对方的ip以及port)
        # udp_socket.sendto(b"hahahah------1----", ("192.168.33.53", 8080))
        udp_socket.sendto(send_data.encode("utf-8"), ("192.168.33.53", 8080))


    # 关闭套接字
    udp_socket.close()
	

if __name__ == "__main__":
    main()

05-绑定端口用来接收数据

import socket

def main():
    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2. 绑定一个本地信息
    localaddr = ("", 7788)
    udp_socket.bind(localaddr)
    # 3. 接收数据
    recv_data = udp_socket.recvfrom(1024)
    # 4. 打印接收到的数据
    print(recv_data)
    # 5. 关闭套接字
    udp_socket.close()

if __name__ == "__main__":
    main()

 

06-解析出接收到的数据

 

import socket

def main():
    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2. 绑定一个本地信息
    localaddr = ("", 7788)
    udp_socket.bind(localaddr)  # 必须绑定自己电脑的ip以及port,其他的不行
    # 3. 接收数据
    recv_data = udp_socket.recvfrom(1024)
    # recv_data这个变量中存储的是一个元组(接收到的数据,(发送方的ip, port))
    recv_msg = recv_data[0]  # 存储接收的数据
    send_addr = recv_data[1]  # 存储发送方的地址信息
    # 4. 打印接收到的数据
    # print(recv_data)
    # print("%s:%s" % (str(send_addr), recv_msg.decode("utf-8")))
    print("%s:%s" % (str(send_addr), recv_msg.decode("gbk")))
    # 5. 关闭套接字
    udp_socket.close()

if __name__ == "__main__":
    main()

循环接收并显示

import socket

def main():
    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2. 绑定一个本地信息
    localaddr = ("", 7788)
    udp_socket.bind(localaddr)  # 必须绑定自己电脑的ip以及port,其他的不行

    # 3. 接收数据
    while True:
        recv_data = udp_socket.recvfrom(1024)
        # recv_data这个变量中存储的是一个元组(接收到的数据,(发送方的ip, port))
        recv_msg = recv_data[0]  # 存储接收的数据
        send_addr = recv_data[1]  # 存储发送方的地址信息
        # 4. 打印接收到的数据
        # print(recv_data)
        # print("%s:%s" % (str(send_addr), recv_msg.decode("utf-8")))
        print("%s:%s" % (str(send_addr), recv_msg.decode("gbk")))
    # 5. 关闭套接字
    udp_socket.close()

if __name__ == "__main__":
    main()

  • 一个udp网络程序,可以不绑定,此时操作系统会随机进行分配一个端口,如果重新运行此程序端口可能会发生变化
  • 一个udp网络程序,也可以绑定信息(ip地址,端口号),如果绑定成功,那么操作系统用这个端口号来进行区别收到的网络数据是否是此进程的

08-先绑定端口然后在循环发送

import socket

def main():
    # 创建一个udp套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 绑定本地信息
    udp_socket.bind(("", 7890))

    while True:

        # 从键盘获取数据
        send_data = input("请输入要发送的数据:")

        # 可以使用套接字收发数据
        # udp_socket.sendto("hahahah", 对方的ip以及port)
        # udp_socket.sendto(b"hahahah------1----", ("192.168.33.53", 8080))
        udp_socket.sendto(send_data.encode("utf-8"), ("192.168.33.53", 8080))


    # 关闭套接字
    udp_socket.close()
	

if __name__ == "__main__":
    main()

应用:udp聊天器

说明

  • 在一个电脑中编写1个程序,有2个功能
  • 1.获取键盘数据,并将其发送给对方
  • 2.接收数据并显示
  • 并且功能数据进行选择以上的2个功能调用

要求

  1. 实现上述程序
import socket


def send_msg(udp_socket):
    """获取键盘数据,并将其发送给对方"""
    # 1. 从键盘输入数据
    msg = input("\n请输入要发送的数据:")
    # 2. 输入对方的ip地址
    dest_ip = input("\n请输入对方的ip地址:")
    # 3. 输入对方的port
    dest_port = int(input("\n请输入对方的port:"))
    # 4. 发送数据
    udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))


def recv_msg(udp_socket):
    """接收数据并显示"""
    # 1. 接收数据
    recv_msg = udp_socket.recvfrom(1024)
    # 2. 解码
    recv_ip = recv_msg[1]
    recv_msg = recv_msg[0].decode("utf-8")
    # 3. 显示接收到的数据
    print(">>>%s:%s" % (str(recv_ip), recv_msg))
    print("-------------------------")


def main():
    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2. 绑定本地信息
    udp_socket.bind(("", 7890))
    while True:
        # 3. 选择功能
        print("="*30)
        print("1:发送消息")
        print("2:接收消息")
        print("="*30)
        op_num = input("请输入要操作的功能序号:")

        # 4. 根据选择调用相应的函数
        if op_num == "1":
            send_msg(udp_socket)
        elif op_num == "2":
            recv_msg(udp_socket)
        else:
            print("输入有误,请重新输入...")

if __name__ == "__main__":
    main()

先可以把能想清楚的写完,正或倒推导就可以,正不行就倒着来。

一个Socket就可以实现数据的发和收,其能实现双工(像电话一样)

单工,电视或收音机

半双工:可以发也可以收但同一时刻只能发或收

127.0.0.1是本机的默认不变的IP,可以自己的电脑上两个程序通讯。