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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3979|回复: 0

Arduino基于UDP协议的远程通信

[复制链接]
发表于 2018-8-27 22:03 | 显示全部楼层 |阅读模式
我们期望实现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[1024];
//创建字节数组,指定接收的数据包的大小
            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[128] = {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


微信图片_20180826203546.jpg

图2

图2

图1

图1
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:48 , Processed in 0.142210 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表