UDP类型客户端
我们知道UDP是一个无连接的传输协议,所以在我们进行编写UDP类型的客户端时我们不用关系其他的一些事情,只管将数据发送出去就行了。
我们想要编写一个客户端,首先我们肯定需要导入Socket包,然后我们创建一个套接字。
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
在这里我们创建socket套接字时,我们传入了两个参数每一个是“socket.AF_INET”,还有一个是“socket.SOCK_DGRAM”。
其中“socket.AF_INET”表示我们使用的协议是IPV4,而“socket.SOCK_DGRAM”表示我们使用的是UDP类型的通讯技术。
当我们创建完套接字后,我们就可以准备发送数据了,在UDP中我们使用的是sendto()进行发送的。
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 设置IP及其端口信息(注意是元祖)
ip_port = (("127.0.0.1"), 1234)
data = "hello"
socket_UDP.sendto(data, ip_port)
运行结果: 我们发现直接报错了,说是要一个字节对象,而不是一个字符串。这里我们就需要对它进行一个编码即可。
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 设置IP及其端口信息(注意是元祖)
ip_port = (("127.0.0.1"), 1234)
data = "hello".encode("utf-8")
socket_UDP.sendto(data, ip_port)
运行结果: 可以很清晰的发现我们收到了来自客户端发送的消息。
这样一个基本的框架就成型了,现在我们想要循环且可控发送数据,代码如下:
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 设置IP及其端口信息(注意是元祖)
ip_port = (("127.0.0.1"), 1234)
while True:
data = input("请输入与你要发送的消息:")
if data == "exit":
break
socket_UDP.sendto(data.encode("utf-8"), ip_port)
socket_UDP.close()
运行结果:
UDP类型服务端
这里我们知道创建UDP服务端我们我们知道下面这几个步骤。
- 创建套接字
- 绑定IP及其端口信息
- 接收来自客户端的信息
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定IP及端口信息
ip_port = (("127.0.0.1"), 123)
socket_UDP.bind(ip_port)
# 接收信息
socket_recv = socket_UDP.recvfrom(1024)
print(socket_recv)
我们首先运行它: 我们通过客户端发送了一个消息后,发现它显示的是一个元祖,所以我们可以将这个接收到的数据抛开列出来。
通过代码一步步的提取,我也成功的把IP,端口,数据这三个数据提取出来了。
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定IP及端口信息
ip_port = (("127.0.0.1"), 123)
socket_UDP.bind(ip_port)
# 接收信息
socket_recv = socket_UDP.recvfrom(1024)
socket_data = socket_recv[0].decode("utf-8")
socket_ip_port = socket_recv[1]
socket_ip = socket_ip_port[0]
socket_port = socket_ip_port[1]
print(socket_data)
print(socket_ip_port)
print(socket_ip)
print(socket_port)
运行: 接下来我们只需要优化一下代码,就可以很清晰的显示出来自客户端的消息了。
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定IP及端口信息
ip_port = (("127.0.0.1"), 123)
socket_UDP.bind(ip_port)
# 接收信息
socket_recv = socket_UDP.recvfrom(1024)
# 提取客户端数据
socket_data = socket_recv[0].decode("utf-8")
# 提取IP及端口信息
socket_ip_port = socket_recv[1]
# 提取IP信息
socket_ip = socket_ip_port[0]
# 提取端口信息
socket_port = socket_ip_port[1]
print("[*] 来自 %s:%s 的信息为:%s" % (socket_ip, socket_port, socket_data))
运行: 很清楚的接收到客户端的信息,你好。
我们也可以写一个循环接收,只用在上面的代码中添加一个while循环即可。
import socket
# 创建套接字
socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定IP及端口信息
ip_port = (("127.0.0.1"), 123)
socket_UDP.bind(ip_port)
while True:
# 接收信息
socket_recv = socket_UDP.recvfrom(1024)
# 提取客户端数据
socket_data = socket_recv[0].decode("utf-8")
# 提取IP及端口信息
socket_ip_port = socket_recv[1]
# 提取IP信息
socket_ip = socket_ip_port[0]
# 提取端口信息
socket_port = socket_ip_port[1]
print("[*] 来自 %s:%s 的信息为:%s" % (socket_ip, socket_port, socket_data))
运行:
功能集合
我们也可以将这些功能全部集合在一起,客户端和服务端都能收都能发。
import socket
def main():
print("请选择功能:\n"
"1. 发送数据\n"
"2. 接收数据\n"
"3. 退出程序")
while True:
choose = int(input("请输入你的选择:"))
# 调用函数
if choose == 1:
UDP_Send()
elif choose == 2:
UDP_Recevice()
elif choose == 3:
exit()
else:
print("输入有误请重新输入!")
def UDP_Recevice():
# 创建套接字
UDP_Socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 设置ip及其端口信息
ip_port = (("127.0.0.1"), 12345)
# 绑定ip及其端口
UDP_Socket.bind(ip_port)
while True:
# 接收发送过来的信息
UDP_data_ip_port = UDP_Socket.recvfrom(1024)
# 优化发送过来的信息,让更具有可读性
UDP_data = UDP_data_ip_port[0].decode("utf-8")
if UDP_data == "exit":
UDP_Socket.close()
break
UDP_ip_port = UDP_data_ip_port[1]
UDP_ip = UDP_ip_port[0]
UDP_port = UDP_ip_port[1]
print("来自%s:%s 的信息:%s" % (UDP_ip, UDP_port, UDP_data))
def UDP_Send():
# 创建套接字
UDP_Socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 设置ip及其端口信息
ip_port = (("127.0.0.1"), 1234)
while True:
# 定义数据包
UDP_data = input("请输入你需要发送的消息:")
UDP_Socket.sendto(UDP_data.encode("utf-8"), ip_port)
if UDP_data == "exit":
UDP_Socket.close()
break
if __name__ == '__main__':
main()