使用Arduino开发ESP32(08):TCP Client与TCP Server使用

2023-05-16

文章目录

  • 目的
  • TCP Client
    • 使用说明
    • 常用方法
    • 基础使用演示
    • 作为WEB Client使用
  • TCP Server
    • 使用说明
    • 常用方法
    • 基础使用演示
    • 作为WEB Server使用
  • 总结

目的

TCP是网络应用中常用的功能,很多高级功能也是建立在TCP的基础上的,学会使用TCP就可以开发很多网络应用了。

TCP Client

TCP Client主要是用来访问服务器的,很多可以通过外网访问的物联网设备主要就是工作在TCP Client下。设备主动去访问外部的服务器,与服务器建立连接,用户的app也是去访问这个服务器,这样变相实现了用户对设备的访问。

使用说明

TCP Client按如下方式使用:

  1. 引用相关库#include <WiFi.h>
  2. 连上网(好像是一句废话)
  3. 声明WiFiClient对象用于连接服务器;
  4. 使用connect方法连接服务器;
  5. 进行数据读写通讯;

常用方法

  • int connect(IPAddress ip, uint16_t port)
    int connect(IPAddress ip, uint16_t port, int32_t timeout)
    int connect(const char *host, uint16_t port)
    int connect(const char *host, uint16_t port, int32_t timeout)
    用于和服务器建立连接,可以连接指定IP地址或是指定域名,连接成功返回1,失败返回0;
  • size_t write(uint8_t data)
    size_t write(const uint8_t *buf, size_t size)
    size_t write_P(PGM_P buf, size_t size)
    size_t write(Stream &stream)
    发送数据,发送成功返回发送字节数,失败返回0;
    除了用write()方法外也可以用print()等方法发送数据;
  • int available()
    返回可读取数据长度,如果没有数据可读取则返回0;
  • int read()
    int read(uint8_t *buf, size_t size)
    从接收缓存读取数据并返回读取到的数据字节数,如果返回-1则表示读取失败,读取过的数据会从接收缓存删除;
  • int peek()
    读取首字节数据,但并不从接收缓存中删除它;
  • void flush()
    清空当前接收缓存;
  • void stop()
    关闭客户端,释放资源;
  • uint8_t connected()
    返回当前客户端是否与服务器建立连接;
  • IPAddress remoteIP() const
    IPAddress remoteIP(int fd) const
    返回服务器IP地址;
  • uint16_t remotePort() const
    uint16_t remotePort(int fd) const
    返回服务器端口号;
  • IPAddress localIP() const
    IPAddress localIP(int fd) const
    返回本地IP地址;
  • uint16_t localPort() const
    uint16_t localPort(int fd) const
    返回本地端口号;

基础使用演示

使用下面代码进行测试:

#include <WiFi.h>

const char *ssid = "********";
const char *password = "********";

const IPAddress serverIP(192,168,50,14); //欲访问的地址
uint16_t serverPort = 50037;         //服务器端口号

WiFiClient client; //声明一个客户端对象,用于与服务器进行连接

void setup()
{
    Serial.begin(115200);
    Serial.println();

    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("Connected");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());
}

void loop()
{
    Serial.println("尝试访问服务器");
    if (client.connect(serverIP, serverPort)) //尝试访问目标地址
    {
        Serial.println("访问成功");

        client.print("Hello world!");                    //向服务器发送数据
        while (client.connected() || client.available()) //如果已连接或有收到的未读取的数据
        {
            if (client.available()) //如果有数据可读取
            {
                String line = client.readStringUntil('\n'); //读取数据到换行符
                Serial.print("读取到数据:");
                Serial.println(line);
                client.write(line.c_str()); //将收到的数据回发
            }
        }
        Serial.println("关闭当前连接");
        client.stop(); //关闭客户端
    }
    else
    {
        Serial.println("访问失败");
        client.stop(); //关闭客户端
    }
    delay(5000);
}

在这里插入图片描述
上图中我们用工具建立的TCP Server进行测试;

作为WEB Client使用

使用下面代码进行测试:

#include <WiFi.h>

const char *ssid = "********";
const char *password = "********";

const char *host = "www.example.com"; //欲访问的域名

void setup()
{
    Serial.begin(115200);
    Serial.println();

    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("Connected");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());
}

void loop()
{
    WiFiClient client; //声明一个客户端对象,用于与服务器进行连接

    Serial.println("尝试访问服务器");
    if (client.connect(host, 80)) //80为一般网站的端口号
    {
        Serial.println("访问成功");

        //向服务器发送请求头,请求网页数据
        //******作为WEB Client使用最核心的就是和WEB Server连接成功后发送相应的请求头请求数据******
        //******WEB Server在收到请求头后返回对应的数据,比如返回网页、图片、文本等******
        //******关于请求头可以参考之前的文章《从零开始的ESP8266探索(06)-使用Server功能搭建Web Server》******
        client.print(String("GET /") + " HTTP/1.1\r\n" +
                     "Host: " + host + "\r\n" +
                     "Connection: close\r\n" +
                     "\r\n");

        //以下代码将收到的网页数据按行打印输出
        //如果是常见的WEB Client(浏览器)的话会将收到的html文件渲染成我们一般看到的网页
        while (client.connected() || client.available()) //如果已连接或有收到的未读取的数据
        {
            if (client.available()) //如果有数据可读取
            {
                String line = client.readStringUntil('\n'); //按行读取数据
                Serial.println(line);
            }
        }

        client.stop(); //关闭当前连接
    }
    else
    {
        Serial.println("访问失败");
        client.stop(); //关闭当前连接
    }
    delay(10000);
}

在这里插入图片描述
上图测试中(虽然是拿了以前的图,但结果是一样的)我们首先去访问 www.example.com(该网址是专门用于测试的),在连接成功后我们向服务器发送请求头请求网页数据,服务器在收到请求头向我们返回了响应头和网页数据(数据可以参考下图,你也可以在浏览器中打开此页面然后右击查看源代码);
在这里插入图片描述

TCP Server

使用说明

TCP Server按如下方式使用:

  • 引用相关库#include <WiFi.h>
  • 声明WiFiServer对象;
  • 使用begin方法启动监听;
  • 监听客户端连接并处理数据通讯;

常用方法

  • WiFiServer(uint16_t port=80, uint8_t max_clients=4)
    在声明WiFiServer对象可以选择输入要监听的端口号和最大接入客户数量;
  • WiFiClient available()
    WiFiClient accept(){return available();}
    尝试建立客户对象;
  • void begin(uint16_t port=0)
    服务器启动监听;
  • void setNoDelay(bool nodelay)
    设置是否延时发送(使用begin方法时会被设置为false,这样服务器会合并小数据包后发送,产生延时);
    开启NoDelay可以提高应答速度,但有些情况下会降低总传输效率,需要根据需求设置;
  • bool getNoDelay()
    返回是否延时发送;
  • bool hasClient()
    返回是否有客户端尝试接入;
  • size_t write(const uint8_t *data, size_t len)
    size_t write(uint8_t data){return write(&data, 1);}
    发送数据,发送成功返回发送字节数,失败返回0;
    除了用write()方法外也可以用print()等方法发送数据;
  • void end()
    void close()
    void stop()
    停止当前监听;
  • int setTimeout(uint32_t seconds)
    设置超时时间;

基础使用演示

使用下面代码进行测试:

#include <WiFi.h>

const char *ssid = "********";
const char *password = "********";

WiFiServer server; //声明服务器对象

void setup()
{
    Serial.begin(115200);
    Serial.println();

    WiFi.mode(WIFI_STA);
    WiFi.setSleep(false); //关闭STA模式下wifi休眠,提高响应速度
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("Connected");
    Serial.print("IP Address:");
    Serial.println(WiFi.localIP());

    server.begin(22333); //服务器启动监听端口号22333
}

void loop()
{
    WiFiClient client = server.available(); //尝试建立客户对象
    if (client) //如果当前客户可用
    {
        Serial.println("[Client connected]");
        String readBuff;
        while (client.connected()) //如果客户端处于连接状态
        {
            if (client.available()) //如果有可读数据
            {
                char c = client.read(); //读取一个字节
                                        //也可以用readLine()等其他方法
                readBuff += c;
                if(c == '\r') //接收到回车符
                {
                    client.print("Received: " + readBuff); //向客户端发送
                    Serial.println("Received: " + readBuff); //从串口打印
                    readBuff = "";
                    break; //跳出循环
                }
            }
        }
        client.stop(); //结束当前连接:
        Serial.println("[Client disconnected]");
    }
}

在这里插入图片描述

作为WEB Server使用

后面会介绍更加方便的WebServer功能,如果想用TCP Server实现这个的话可以参考官方例程:
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/SimpleWiFiServer
或是下面文章:
《从零开始的ESP8266探索(06)-使用Server功能搭建Web Server》

总结

TCP Client与TCP Server的基本使用主要就是上面这些了,结合之前的UDP功能,已经可以开发很多网络应用了。更多内容可以参考如下:
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi
另外如果作为客户端使用有安全方面需求可以参考下面连接:
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFiClientSecure

The WiFiClientSecure class implements support for secure connections using TLS (SSL). It inherits from WiFiClient and thus implements a superset of that class’ interface. There are three ways to establish a secure connection using the WiFiClientSecure class: using a root certificate authority (CA) cert, using a root CA cert plus a client cert and key, and using a pre-shared key (PSK).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Arduino开发ESP32(08):TCP Client与TCP Server使用 的相关文章

  • Soap Delphi 客户端因 1MB 调用超时而结束

    我们正在开发 SOAP Web 服务 Apache PHP 所有小规模调用都运行良好 但对于 1Mb 的 Soap 调用 HTTPS 调用大小为 1MB 我们的 Delphi Soap 客户端在除一台 PC 之外的所有 PC 上都因超时而停
  • 套接字发送调用被阻塞很长时间

    我每 10 秒在套接字上发送 2 个字节的应用程序数据 阻塞 但发送调用在下面的最后一个实例中被阻塞超过 40 秒 2012 06 13 12 02 46 653417 信息 发送前 2012 06 13 12 02 46 653457 信
  • Grpc - 将消息从一个客户端发送到连接到同一服务器的另一个客户端

    是否可以将消息从一个客户端发送到连接到同一服务器的另一个客户端 我想将数据从一个客户端发送到服务器然后发送到特定客户端 我想我需要获取客户端 ID 但我不知道如何获取此 ID 以及如何从服务器将此消息发送到该客户端 我这里有一个样本 这是一
  • 网络服务发现不是发现服务类型

    我想通过 Android 设备在本地网络中找到服务器 我可以通过使用找到它NSDManager具有服务器服务类型的服务 例如 workstation tcp是服务类型 在我的本地网络中我有一个 无线路由器和无线中继器 两者都有不同的SSID
  • 如何在 C# 中向肥皂信封添加命名空间

    我想向我的肥皂信封添加命名空间设置 我想在 IClientMessageInspector 的 BeforeSendRequest 中更改它 或者您有更优雅的方法 例如
  • C#:如何在 Socket.BeginReceive 回调之前终止套接字?

    我有一个接收来自客户端的连接请求的服务器 该服务器使用异步Socket BeginReceive and Socket EndReceive方法 该代码与找到的代码非常相似here http msdn microsoft com en us
  • 如何与使用 child_process.spawn 创建的新创建的服务器交互

    我正在尝试为我的私人托管的 反恐精英全球攻势 服务器制作一个前端 当我点击运行服务器时 在前端 一切正常 服务器启动并记录到控制台 但是如何查看服务器IP地址 服务器中的玩家等信息呢 这是我到目前为止运行服务器的内容 router post
  • 防止使用 golang 服务器访问文件夹中的文件

    我在 golang 中有一个服务器可以处理这样的文件夹路径 fs http FileServer http Dir assets http Handle Images fs http ListenAndServe 8000 nil 但在这个
  • TCP 中推送标志和紧急标志之间的区别

    我试图理解带有标志的 TCP 段之间的区别PSH和旗帜URG 我阅读了 RFC 但仍然无法获取它 其中一个在将数据发送到进程之前是否缓冲数据 而另一个则没有 它们是两种截然不同的机制 PSH 和 PUSH 函数 当您发送数据时 您的TCP缓
  • WCF 包装代理客户端

    我的项目中有许多在客户端应用程序中使用的 Web 方法 我不想写这样的代码 using ServiceClient sc new ServiceClient Invoke service methods sc Method1 相反 我想写
  • C:为什么这个服务器/客户端设置只能在一台计算机上运行?

    我是网络新手 我想知道为什么会这样TCP 服务器 客户端 C 语言实现 https www geeksforgeeks org tcp server client implementation in c 只能在一台计算机上运行 1 我的意思
  • Neo4j 服务器无法使用非托管扩展启动

    我正在尝试在 neo4j 服务器 版本 CE 2 3 2 上使用非托管扩展 所以我正在尝试一个简单的你好世界的例子 http neo4j com docs stable server unmanaged extensions htmlNeo
  • 是否值得为 EEPROM 实现小型文件系统

    我买了一个I2C EEPROM 我想存储传感器和电压数据 我假设该值可以大于一个字节 并且可以有很多数据 在这种情况下是否值得实现具有小文件分配表的文件系统 例如 这会让我更容易查看 EEPROM 我发现 EEPROM 上出现 FAT 有两
  • ConnectionTimeout 与 SocketTimeout

    我正在使用的库有问题 可能是图书馆的问题 也可能是我用错了 基本上 当我这样做时 超时以毫秒为单位 ignitedHttp setConnectionTimeout 1 v short ignitedHttp setSocketTimeou
  • Arduino 上的串行消息到整数

    我希望我的 Arduino 通过串行通信接收一个整数 你能帮我解决这个问题吗 它应该是这样的形式 int value strtoint Serial read 有多种方法可以读取整数Serial 很大程度上取决于数据发送时的编码方式 Ser
  • SO_REUSEPORT 可以在 Unix 域套接字上使用吗?

    Linux 内核 gt 3 9 允许通过设置在内核负载平衡的进程之间共享套接字SO REUSEPORT http lwn net Articles 542629 http lwn net Articles 542629 这如何用于类型的套接
  • 10G 链路的 netcat 和 iperf 结果存在巨大差异

    我很困惑看到 netcat 和 iperf 结果之间的巨大差异 我有 10 G 链路连接我的服务器和客户端 iperf 的速度约为 10Gb s 但 netcat 的速度仅为约 280 MB s 可能是什么错误 对于 Iperf Serve
  • Arduino 引导加载程序

    有人可以解释一下如何Arduino引导加载程序 http code google com p arduino source browse tags 0019 hardware arduino bootloaders atmega ATmeg
  • Jmeter TCP Sampler - 如何重用线程之间的连接?

    我在 JMeter 的 ThreadGroup 下设置了一个 TCP 采样器 数据是从 CSV 文件中选取的 第一行数据用于认证 后续行为实际参数数据 像下面这样的东西 AAAAAAA21 BBBBBBBCCCCCCCDDDDDDD BBB
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100

随机推荐

  • CrowdHuman数据集介绍

    CrowdHuman数据集是旷世发布的用于行人检测的数据集 xff0c 图片数据大多来自于google搜索 CrowdHuman 数据集数据量比较大 xff0c 训练集15000张 xff0c 测试集5000张 xff0c 验证集4370张
  • CityPersons数据集介绍

    CityPersons数据集是cityscape的一个子集 xff0c 它只包含个人注释 有2975张图片用于培训 xff0c 500张和1575张图片用于验证和测试 一幅图像中行人的平均数量为7人 xff0c 提供了可视区域和全身标注 C
  • CUHK-SYSU数据集介绍

    该数据集是一个大规模的人员搜索基准 xff0c 包含18184张图像和8432个身份 根据图像来源 xff0c 数据集可以分为两部分 xff1a 街道捕捉和电影 xff1a 在街拍中 xff0c 图像通过手持摄像机收集 xff0c 跨越数百
  • ETHZ数据集介绍

    Ess等构建了基于双目视觉的行人数据库用于多人的行人检测与跟踪研究 该数据库采用一对车载的AVT Marlins F033C摄像头进行拍摄 xff0c 分辨率为640 480 xff0c 帧率13 14fps xff0c 给出标定信息和行人
  • Swin Transformer V2

    Swin Transformer V2 论文链接 xff1a https arxiv org pdf 2111 09833 pdf 代码链接 xff1a https github com microsoft Swin Transformer
  • Jetson_Xavier_NX使用教程1(刷机)

    刷机教程 一 xff1a 准备 1 xff1a 准备需要一个tf卡 xff0c 容量最好大点 xff0c 我买的128G的 2 xff1a 还有两个软件一个是格式化卡的软件 xff0c 一个是将镜像文件写入的卡的软件 格式化卡的软件 写入镜
  • Jetson_Xavier_NX使用教程2(简单实用)

    本文会介绍一些刷机后的基本操作 1 风扇控制 刚开始插入电源风扇不转我以外坏了 xff0c 后来才发现并没有 Xavier NX的风扇在系统内核中有一套自动控制温度和转速的算法 xff0c 经过我观察大约在40度左右的时候会自动开启风扇进行
  • NVIDIA Jetson NX使用教程3配置pytorch环境

    本节主要记录 xff0c 安装pytorch及torch vision 1 下载Pytorch 因为jetson属于arm架构的机器 xff0c 所以需要去nvidia的官网下载对应的安装包而不是pytroch的官网 官网链接 xff0c
  • Java 基于 IETF RFC 2617 身份认证

    IETF RFC 2617 身份认证 是基于 HTTP 协议进行验证的 xff0c 认证过程中需要发送两次 HTTP 请求 xff0c 第一次请求服务器返回 401 和 认证标识 xff08 nonce xff09 xff0c 第二次访问H
  • 判断一台机器是大端序还是小端序

    在几乎所有的机器上 xff0c 多字节对象都被存储为连续的字节序列 例如在C语言中 xff0c 一个类型为int的变量x地址为0x100 xff0c 那么其对应地址表达式 amp x的值为0x100 且x的四个字节将被存储在存储器的0x10
  • STL容器保存智能指针并将this指针通过emplace传入STL容器所造成的致命问题(【double free or corruption (out)】和【bad_weak_ptr】)

    我用std queue保存了一个Message类型的智能指针 queue lt shared ptr lt MessageA gt xff0c 然后在Message类型中来将this指针插入队列 xff0c 使用std queue push
  • 实时动态定位(RTK)

    内容来着网络 实时动态定位 xff1a Real Time Kinematic RTK技术的关键在于使用了GPS的载波相位观测量 xff0c 并利用了参考站和移动站之间观测误差的空间相关性 xff0c 通过差分的方式除去移动站观测数据中的大
  • 几个实用的 Bat 脚本命令

    文章目录 1 截图2 息屏后锁屏3 查看当前的路径4 倒计时5 密码输入6 比较两个文本的差异 1 截图 start snippingtool 2 息屏后锁屏 powershell Add Type 39 DllImport 34 user
  • 学习cmake的使用和CMakeLists.txt

    1 学习cmake的使用和CMakeLists txt 文章目录 1 学习cmake的使用和CMakeLists txt1 1 cmake外部构建基础1 2 让每个源文件目录都包含一个CMakeLists txt1 3 安装 1 4 构建静
  • ROS系统基础知识梳理(四) 串口通信

    ROS系统基础知识梳理 四 串口通信 学习ROS系统 xff0c 初步接触到ROS系统外接传感器 xff0c 传感器通过Uart通信向台式机发送数据 xff0c 内容涉及到ROS调用串口数据 串口数据校验 以及欧拉角转换四元数 任务系统 x
  • Keil5中添加新的.c和.h文件

    目录 在Project的文件夹中添加添加路径使用include 在Project的文件夹中添加 如图1所示 xff0c 在User的文件夹上右键 xff0c 添加已有文件 图1 添加路径 然后需要在options for Target xf
  • 学习c语言的总结

    学习时间 xff1a 早上9点 晚上9点 学习内容 xff1a 利用c语言对 的代码学习 xff0c 并根据自己的理解编写代码 xff0c 最后整合学习的代码和自己理解的代码 xff0c 编写出更优的代码 学习体会 xff1a 对一个问题举
  • C/C++程序编译成可执行程序步骤图文源码详解

    一个C 43 43 程序被编译为目标程序的过程中经历了四个部分 xff0c 分别是预处理 编译 汇编 链接 下面将通过一个简单的C 43 43 代码分别执行预处理 编译 汇编 链接四个步骤后的结果和基本原理讲解 注意 xff1a 博主是在u
  • 【linux】程序找不到动态库.so的解决办法|查看.so动态库信息|.so动态库加载顺序

    目录 找不到 so解决方法 方法一 xff1a 添加环境变量 方法二 xff1a 复制so文件到lib路径 方法三 xff1a xff08 推荐 xff09 添加ldconfig寻找路径 方法四 xff1a 在编译目标代码时指定该程序的动态
  • 使用Arduino开发ESP32(08):TCP Client与TCP Server使用

    文章目录 目的TCP Client使用说明常用方法基础使用演示作为WEB Client使用 TCP Server使用说明常用方法基础使用演示作为WEB Server使用 总结 目的 TCP是网络应用中常用的功能 xff0c 很多高级功能也是