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)

serverA.py

# -*- 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端通信的端口号是不同的。

serverB.py

# -*- 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)

在终端运行结果如图:
UDP通信——通过UDP进行转发
实现了这一步,就可以在此基础上再进行改进了。

二、 让 client 和 serverA 正常通信, serverA 每隔一定时间向 serverB 发送一个信号用于监控 serverA 的运行。
要实现上面的目的,需要对serverA稍加改动:

serverA.py

# -*- 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"

结果如图所示:
UDP通信——通过UDP进行转发
可以看到,client 以不同的时间间隔向 serverA 发送数据,但 serverA 只有在接收两次数据的时间间隔大于2秒时才向 serverB 发送信号!

还可以改动一下,让 serverA 接收的数据满足一定条件时向 serverB 发信号,比如:

serverA.py

# -*- 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"

结果如图:
UDP通信——通过UDP进行转发