UDP通信——通过UDP进行转发
UDP通信——通过UDP通信进行数据转发
想象一下这样的应用场景:我要从设备A向设备B发送数据,B根据接收到的数据信息向设备C发送数据(当然不一定分别是3个不同的设备),如何用UDP通信实现呢?
可以由易到难的试验,一步步来实现:
一、 编写1个client,2个server,每次向client输入一个数据,让它发给serverA,然后serverA把收到的信息发给serverB。
发送端 client.py
# -*- coding: utf-8 -*-
import socket
import time
#client 发送端
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
PORT = 8000
while True:
start = time.time() #获取当前时间
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(start))) #以指定格式显示当前时间
msg=raw_input("本客户端192.168.43.131,请输入要发送的内容:")
server_address = ("192.168.43.131", PORT) # 接收方 服务器的ip地址和端口号
client_socket.sendto(msg, server_address) #将msg内容发送给指定接收方
now = time.time() #获取当前时间
run_time = now-start #计算时间差,即运行时间
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now)))
print("run_time: %d seconds\n" %run_time)
# -*- coding: utf-8 -*-
import socket
import time
#server 接收端
PORT1 = 8000 #用于与client通信
PORT2 = 9000 #用于与serverB通信
address1 = ("192.168.43.131", PORT1) #用于接收client数据
address2 = ("192.168.43.131", PORT2) #用于向serverB发送数据
serverA_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 为服务器绑定一个固定的地址,ip和端口
serverA_socket.bind(address1) #与client通信是接收端,所以要绑定与client通信的地址,
serverA_socket.settimeout(10) #10秒钟未收到数据则进行提示
while True:
try:
now = time.time()
receive_data, client = serverA_socket.recvfrom(1024)
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now)))
print("来自客户端%s,发送的: %s\n" % (client, receive_data))
for i in range(0,1): #每次接收的数据只向serverB发送1次
serverA_socket.sendto(receive_data,address2)
i=i+1
except socket.timeout:
print "tme out"
serverA.py中的for循环语句是为了保证每次接收到的数据只向serverB发送1次,如果没有这个循环语句而是直接把sendto函数写在while循环里面,会导致虽然接收了1次数据,但是会不停地向serverB发送。另外要注意的就是与client端和serverB端通信的端口号是不同的。
# -*- coding: utf-8 -*-
import socket
import time
#server 接收端
PORT = 9000
serverB_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
address = ("192.168.43.131", PORT)
serverB_socket.bind(address)
while True:
receive_data, client = serverB_socket.recvfrom(1024)
now = time.time()
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now)))
print("来自客户端%s,发送的: %s\n" % (client, receive_data))
# server_socket.sendto(receive_data, client)
在终端运行结果如图:
实现了这一步,就可以在此基础上再进行改进了。
二、 让 client 和 serverA 正常通信, serverA 每隔一定时间向 serverB 发送一个信号用于监控 serverA 的运行。
要实现上面的目的,需要对serverA稍加改动:
# -*- coding: utf-8 -*-
import socket
import time
#server 接收端
PORT1 = 8000 #用于与client通信
PORT2 = 9000 #用于与serverB通信
address1 = ("192.168.43.131", PORT1) #用于接收client数据
address2 = ("192.168.43.131", PORT2) #用于向serverB发送数据
serverA_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 为服务器绑定一个固定的地址,ip和端口
serverA_socket.bind(address1) #与client通信是接收端,所以要绑定与client通信的地址,
serverA_socket.settimeout(10) #10秒钟未收到数据则进行提示
while True:
try:
now = time.time()
receive_data, client = serverA_socket.recvfrom(1024)
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now)))
print("来自客户端%s,发送的: %s\n" % (client, receive_data))
if time.time()>=now +2: #接收数据时间间隔大于2秒钟,则执行下面代码
for i in range(0,1): #每次接收的数据只向serverB发送1次
serverA_socket.sendto(receive_data,address2)
i=i+1
except socket.timeout:
print "tme out"
结果如图所示:
可以看到,client 以不同的时间间隔向 serverA 发送数据,但 serverA 只有在接收两次数据的时间间隔大于2秒时才向 serverB 发送信号!
还可以改动一下,让 serverA 接收的数据满足一定条件时向 serverB 发信号,比如:
# -*- coding: utf-8 -*-
import socket
import time
#server 接收端
PORT1 = 8000 #用于与client通信
PORT2 = 9000 #用于与serverB通信
address1 = ("192.168.43.131", PORT1) #用于接收client数据
address2 = ("192.168.43.131", PORT2) #用于向serverB发送数据
serverA_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 为服务器绑定一个固定的地址,ip和端口
serverA_socket.bind(address1) #与client通信是接收端,所以要绑定与client通信的地址,
serverA_socket.settimeout(10) #10秒钟未收到数据则进行提示
while True:
try:
now = time.time()
receive_data, client = serverA_socket.recvfrom(1024)
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now)))
print("来自客户端%s,发送的: %s\n" % (client, receive_data))
if int(receive_data) >= 100: #接收数据大于100,则执行下面代码,注意类型转换
for i in range(0,1): #每次接收的数据只向serverB发送1次
serverA_socket.sendto(receive_data,address2)
i=i+1
except socket.timeout:
print "tme out"
结果如图: