Arduino基于UDP协议的远程通信-Arduino中文社区 - Powered by Discuz! Archiver

destild 发表于 2018-8-27 22:03

Arduino基于UDP协议的远程通信

我们期望实现Arduino+ESP8266来实现终端和服务器之间的远程通信,在文章《Arduino+ESP8266上传数据到服务器》中,实现了将终端的数据上传到服务器,在文章《Arduino+ESP8266接收服务器信息》中,实现了终端手动接收服务器的信息。这两篇文章都只是一个铺垫,没有真正的实现远程通信的功能。我们在编程测试过程中,始终无法实现这种基于TCP协议的远程通信(可能是代码的bug,也可能是其他未知的原因),我们在之前的一文章《Arduino+ESP8266接收服务器信息——源代码分析》中,也专门对源码进行了分析,暂时没有找到原因。如果读者知道其中的原因,请不吝赐教。换一个角度,我们期望通过基于UDP协议的远程通信,在文章《TCP,UDP通信使用场景及区别比较》中,对于TCP和UDP协议进行了简单的比较,同时在我们在Eclipse上模拟实现了终端和服务器间基于UDP的通信。本文,我们将实现Arduino+ESP8266搭建的终端平台和服务器之间的基于UDP的远程通信。服务器源代码

package udpserver.damuchacha;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UDPServer {
   public static void main(String[] args) throws IOException {
          //接收客户端发送的数据   
            DatagramSocket socket = new DatagramSocket(8800);
            // 1.创建服务器端DatagramSocket,指定端口
            // 2.创建数据报,用于接收客户端发送的数据
            byte[] data = new byte;//创建字节数组,指定接收的数据包的大小
            DatagramPacket packet = new DatagramPacket(data, data.length);
            // 3.接收客户端发送的数据
            
            System.err.println("Server:");//输出服务器的标识
         while(true) {//通过循环不停的向客户端发送数据和接收数据
            socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
            // 4.读取数据
            String info = new String(data, 0, packet.getLength());//创建字符串对象
            System.out.println("服务器接收到客户端的信息是:" + info);//输出提示信息
            
          //向客户端响应数据
            // 1.定义客户端的地址、端口号、数据
            System.out.println("回复客户端的消息:");
            InetAddress address = packet.getAddress();
            //获取发送端的地址
            int port = packet.getPort();
            //获取 发送端进程所绑定的端口
            Scanner scanner = new Scanner(System.in);
          //从键盘接受数据
            String send = scanner.nextLine();
          //nextLine方式接受字符串
            byte[] data2 = send.getBytes();
            //将接收到的数据转换为字节数组
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address,port);
            // 2.创建数据报,包含响应的数据信息      
            socket.send(packet2);
          // 3.响应客户端
         }
      }
}

客户端源代码

#include "ESP8266.h"
#include<SoftwareSerial.h>
#define WIFI_TX 9
#define WIFI_RX 8

#define SSID      "Destiny Child"
#define PASSWORD    "di*********n"
#define HOST_NAME   "172.20.10.9"
#define HOST_PORT   8800
SoftwareSerial mySerial(WIFI_RX,WIFI_TX);
ESP8266 wifi(mySerial,115200);

void setup(void)
{
    Serial.begin(230400);
    Serial.print("setup begin\r\n");
   
    Serial.print("FW Version:");
    Serial.println(wifi.getVersion().c_str());
    // 设置操作模式
    while(wifi.setOprToStationSoftAP()==false){
      Serial.print("waiting for setting operating mode station + softap ...\r\n");
      delay(100);
    }
    Serial.print("operating mode station + softap ok\r\n");
//连接WiFi
    while(wifi.joinAP(SSID, PASSWORD)==false){
      Serial.print("waiting for joining AP...\r\n");
      delay(100);
    }
    Serial.print("Join AP success\r\n");
    //WiFi连接成功后打印IP地址
    Serial.print("IP:");
    Serial.println( wifi.getLocalIP().c_str());
   
//设置连接模式   
    while(wifi.disableMUX()==false){
      Serial.print("waiting for single connecting mode TCP or UDP ...\r\n");
      delay(100);
    }
    Serial.print("single mode ok\r\n");
    Serial.print("setup success\r\n");
}

void loop(void)
{
    uint8_t buffer = {0};

    while(wifi.registerUDP(HOST_NAME, HOST_PORT)==false){
      Serial.print("register udp err\r\n");
      delay(100);
    }
    Serial.print("register udp ok\r\n");
   

    char *hello = "Hello, this is client!";
    wifi.send((const uint8_t*)hello, strlen(hello));//发送数据
    uint32_t len = wifi.recv(buffer, sizeof(buffer), 10000);//接收数据
    if (len > 0) {//打印数据
      Serial.print("Received:[");
      for(uint32_t i = 0; i < len; i++) {
            Serial.print((char)buffer);
      }
      Serial.print("]\r\n");
    }
   
    if (wifi.unregisterUDP()) {
      Serial.print("unregister udp ok\r\n");
    } else {
      Serial.print("unregister udp err\r\n");
    }
    delay(5000);
}
服务器输出
见图1

客户端输出

见图2

通过服务器和终端的输出结果可以看出,服务器和终端之间能够成功的进行通信。不足的地方是,终端有时候会漏接服务器的信息,有时候接收到的信息会出错。后续的学习过程我们会继续进行完善。

完2018/8/27


页: [1]
查看完整版本: Arduino基于UDP协议的远程通信