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[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[i]);
        }
        Serial.print("]\r\n");
    }
    
    if (wifi.unregisterUDP()) {
        Serial.print("unregister udp ok\r\n");
    } else {
        Serial.print("unregister udp err\r\n");
    }
    delay(5000);


服务器输出


客户端输出

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


 


 

2018/8/27

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值