精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于rt-thread的socket通信設計

冬至子 ? 來源:Zzxy ? 作者:Zzxy ? 2023-10-13 15:02 ? 次閱讀

最近再研究 rt-thread通信 ,想設計出 eps8266(多個)<-> rt-thread(作為中控) <-> 服務器的通信框架,使用的開發板是 潘多拉
首先我們需要 確保使用的開發板可以聯網,其次 我們需要在rt-setting 中打開套接字抽象層
如圖

1.jpg

下載樣例后,把IoT_Boardrt-threadexamplesnetwork 下的tcpserver.c 和 tcpclient.c拿出來放到我們的工程中。

這兩個文件提供了tcp連接指令給我們
具體使用方法如圖。

1.jpg

在進行下一步前最好測試一下這兩個指令是否生效。

為了接下來能看懂,我這邊簡單介紹一些 esp8266的邏輯 ,
連接wifi -> 連接終端(即rt-thread)->首次連接發送設備id-> 循環查看是否接受到數據,如果接收到即對指令進行處理,否則發送當前設備的狀態
接下來看一下終端這邊的邏輯,終端首先要連接wifi ,之后提供 tcpserver 等待 esp8266連接,在esp8266連接上后,創建一個線程,線程名為設備id,再將線程socket資源放到一個全局結構體中,用于之后的維護。

Tcpserver.c 中沒有多少修改的,我只粘貼修改的部分
在tcpserv函數中,在receive 后修改如下

bytes_received = recv(connected, str, BUFSZ, 0);
if (bytes_received < 0)
{
    LOG_E("Received error, close the connect.");
    closesocket(connected);
    connected = -1;
    break;
}
else
{
    /* 在控制終端顯示收到的數據 */
    rt_thread_t tid;
    LOG_D("Received threadName = %s n", str,str);
    tid = rt_thread_create(str,
        tcpserver_to_client, (void *)connected,
        1024, RT_THREAD_PRIORITY_MAX/3, 20);
    if (tid != RT_NULL)
    {
        sockets.tids[sockets.len]=tid;
        sockets.connects[sockets.len]=connected;
        sockets.len++;
        rt_thread_startup(tid);
    }
}

即和上面的邏輯一樣,創建通信的線程,將線程資源和socket資源放到全局結構體中維護,結構體的定義如下

1.jpg

接下來看通信線程,代碼如下

static void tcpserver_to_client(void conn){
int running=1;
int bytes_received,connected;
char str[20];
connected = (int)conn;
/
客戶端連接的處理 /
while (running)
{
/
從connected socket中接收數據,接收buffer是1024大小,但并不一定能夠收到1024大小的數據 /
bytes_received = recv(connected, str, BUFSZ, 0);
if (bytes_received < 0)
{
LOG_E("Received error, close the connect.");
closesocket(connected);
connected = -1;
return ;
}
else
{
/
在控制終端顯示收到的數據 */
rt_mb_send(&mb, (rt_uint32_t)&str);
}
}
}

在這個線程中,通過傳遞的socket資源,接受數據,注意這邊的recv是阻塞的,如果接受到數據,就將數據發送到郵箱中,這邊為什么要使用郵箱呢,以為后續我們需要和tcpclient線程進行通信,在esp8266發送消息給我們后,我們需要將消息轉發給服務器。

在繼續講解rt-thread邏輯前我們來看一下服務器的邏輯,服務器邏輯比較簡單,就是提供sever服務,接受tcpclient的數據,并且給tcpclient發送消息,注意服務器端的recv是非阻塞的

接下來看tcpclient的邏輯,在tcpclient中,我們既需要將esp8266的數據轉發給服務器,也需要接受服務器傳的數據,所以我們在這邊的recv不能是阻塞的,那怎么將esp8266的消息轉發呢,就是用之前的郵箱來通信啦,代碼如下

while (is_running)
{
/* 從sock連接中接收最大BUFSZ - 1字節數據 /
bytes_received = recv(sock, recv_data, BUFSZ - 1, MSG_DONTWAIT);
if (bytes_received > 0)
{
char threadName[10]={0};
rt_strncpy(threadName, recv_data, 4);
/
有接收到數據,把末端清零 /
recv_data[bytes_received] = '?';
/
在控制終端顯示收到的數據 /
rt_kprintf("Received data = %sn", recv_data);
send_client(threadName,recv_data);
}
if(get_mailbox()==RT_TRUE){
/
發送數據到sock連接 /
ret = send(sock, str, rt_strlen(str), 0);
if (ret < 0)
{
/
接收失敗,關閉這個連接 /
rt_kprintf("send error, close the socket.");
goto __exit;
}
else if (ret == 0)
{
/
打印send函數返回值為0的警告信息 */
rt_kprintf("Send warning, send function return 0.");
}
}
rt_thread_mdelay(3000);
}

在這段代碼中,recv 的flag 改成了MSG_DONTWAIT 這是revc非阻塞的標志,
比較關鍵的是recv后面的內容,在接受數據后,會取出數據的前四位(前四位為設備id),并且通過send_client 來判斷,如果前四位和之前創建的線程名一樣,就把數據發送給對應的設備send_client函數如下

void send_client(char threadName[],char recvData[]){
int i,ret;
for(i=0;i {
if(rt_strcmp(threadName, (sockets.tids[i])->name)==0){
rt_kprintf("find order to %sn",threadName);
ret = send(sockets.connects[i], recvData, rt_strlen(recvData), 0);
if (ret < 0)
{
/* 接收失敗,關閉這個連接 /
rt_kprintf("send error n");
}
else if (ret == 0)
{
/
打印send函數返回值為0的警告信息 */
rt_kprintf("Send warning, send function return 0.n");
}
}
}
}

get_mailbox()函數是判斷郵箱中是否有東西,有的話就放到str中,并且發送給服務器get_mailbox 函數代碼如下

static int get_mailbox(){
if (rt_mb_recv(&mb, (rt_ubase_t *)&str, RT_WAITING_NO) == RT_EOK)
{
rt_kprintf("thread1: get a mail from mailbox, the content:%d, str1= %sn",str,str);
return RT_TRUE;
}
return RT_FALSE;
}

以上就是實現的流程了,其實還是比較簡單的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 控制器
    +關注

    關注

    112

    文章

    16198

    瀏覽量

    177398
  • Socket
    +關注

    關注

    0

    文章

    211

    瀏覽量

    34632
  • RT-Thread
    +關注

    關注

    31

    文章

    1272

    瀏覽量

    39919
  • ESP8266
    +關注

    關注

    50

    文章

    962

    瀏覽量

    44830
  • TCP通信
    +關注

    關注

    0

    文章

    146

    瀏覽量

    4217
收藏 人收藏

    評論

    相關推薦

    RT-Thread記錄(二、RT-Thread內核啟動流程)

    在前面我們RT-Thread Studio工程基礎之上講一講RT-Thread內核啟動流程.
    的頭像 發表于 06-20 00:30 ?4965次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(二、<b class='flag-5'>RT-Thread</b>內核啟動流程)

    求一種基于RT-Threadsocket通信方案

    最近再研究 rt-thread通信 ,想設計出 eps8266(多個)<-> rt-thread(作為中控) <-> 服務器的通信框架
    發表于 02-07 11:13

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開發組(2015-03-31)。RT-Thread做為國內有較大影響力的開源實時操作系統,本文是RT-Thread實時操作系統的編程指南
    發表于 11-26 16:06 ?0次下載

    RT-Thread用戶手冊

    RT-Thread用戶手冊——本書是RT-Thread的編程手冊,用于指導在RT-Thread實時操作系統環境下如何進行編 程。
    發表于 11-26 16:16 ?0次下載

    RT-Thread全球技術大會:螢石研發團隊使用RT-Thread的技術挑戰

    RT-Thread全球技術大會:研發團隊使用RT-Thread的技術挑戰 ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 11:36 ?1281次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:螢石研發團隊使用<b class='flag-5'>RT-Thread</b>的技術挑戰

    RT-Thread全球技術大會:Kconfig在RT-Thread中的工作機制

    RT-Thread全球技術大會:Kconfig在RT-Thread中的工作機制 ? ? ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 14:49 ?1501次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:Kconfig在<b class='flag-5'>RT-Thread</b>中的工作機制

    RT-Thread全球技術大會:在RT-Thread上編寫測試用例

    RT-Thread全球技術大會:在RT-Thread上編寫測試用例 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 16:28 ?1452次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:在<b class='flag-5'>RT-Thread</b>上編寫測試用例

    RT-Thread全球技術大會:RT-Thread測試用例集合案例

    RT-Thread全球技術大會:RT-Thread測試用例集合案例 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 16:34 ?2057次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:<b class='flag-5'>RT-Thread</b>測試用例集合案例

    RT-Thread學習筆記 RT-Thread的架構概述

    RT-Thread 簡介 作為一名 RTOS 的初學者,也許你對 RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會逐漸發現 RT-Thread 的魅力和它相較于其他同類型 RTOS
    的頭像 發表于 07-09 11:27 ?4482次閱讀
    <b class='flag-5'>RT-Thread</b>學習筆記 <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread文檔_RT-Thread 簡介

    RT-Thread文檔_RT-Thread 簡介
    發表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡介

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文檔_線程間通信

    RT-Thread文檔_線程間通信
    發表于 02-22 18:29 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_線程間<b class='flag-5'>通信</b>

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學習

    前期準備:從官網下載 RT-Thread Studio,弄個賬號登陸,開啟rt-thread學習之旅。
    的頭像 發表于 05-15 11:00 ?3823次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學習

    rt-thread源碼分析之socket抽象層和網卡注冊

    如圖所示,rt-thread的網絡分為應用層、sal_socket、netdev、協議簇(at、lwip、wiznet)、網卡驅動五層。
    的頭像 發表于 11-13 12:43 ?806次閱讀