0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分享一種很簡單的不阻塞TCP發(fā)送方法

冬至子 ? 來源:BruceTan ? 作者:BruceTan ? 2023-09-20 14:23 ? 次閱讀

背景介紹

最近在做一個功能的時候,要求將采集到的數(shù)據(jù)發(fā)送到TCP Server上,TCP Server有時候可能會出問題連接不上,這時候如果使用普通的TCP編程,就會造成數(shù)據(jù)采集的代碼被阻塞了。

為了解決這個問題,我將TCP發(fā)送的代碼使用一個單獨(dú)的線程實(shí)現(xiàn),數(shù)據(jù)采集的代碼在另外一個線程實(shí)現(xiàn),兩個線程之間使用消息隊(duì)列進(jìn)行通信,這樣既不會破壞TCP編程的基礎(chǔ)模型,又可以實(shí)現(xiàn)應(yīng)用代碼非阻塞發(fā)送TCP數(shù)據(jù)。

代碼實(shí)現(xiàn)

代碼實(shí)現(xiàn)如下,當(dāng)采集到數(shù)據(jù)的時候,只需要調(diào)用tcp_client_no_block_send函數(shù)發(fā)送數(shù)據(jù)即可。

#include
#include
#include
#include
#include
#include
#include
#define DBG_TAG "tcp_client"
#define DBG_LVL DBG_INFO
#include
typedef struct
{
uint8_t data[512];
uint32_t len;
}S_MSG, P_MSG;
static rt_mq_t mq = RT_NULL;
static void tcp_client_thread_entry(void
parameter)
{
int sockfd;
struct sockaddr_in server_addr;
S_MSG msg;
SOCKET_INIT:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 )
{
LOG_E("create socket failed.");
return;
}
rt_memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");
server_addr.sin_port = htons(10086);
if( connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(server_addr)) < 0 )
{
LOG_E("connect failed");
closesocket(sockfd);
goto SOCKET_INIT;
}
while(1)
{
if( rt_mq_recv(mq, &msg, sizeof(msg), RT_WAITING_FOREVER) != RT_EOK )
{
continue;
}
if( send(sockfd, msg.data, msg.len, 0) <= 0 )
{
closesocket(sockfd);
goto SOCKET_INIT;
}
}
}
int tcp_client_no_block_send(const uint8_t *data, uint32_t len)
{
RT_ASSERT(mq!=RT_NULL);
RT_ASSERT(data!=RT_NULL);
S_MSG msg;
if( len > sizeof(msg.data) )
{
LOG_E("send len overflow");
return -1;
}
msg.len = len;
rt_memcpy(msg.data, data, len);
if( rt_mq_send(mq, &msg, sizeof(msg)) == -RT_EFULL )
{
//LOG_E("tcp client msg overflow!");
}
return 0;
}
static int tcp_client_init(void)
{
mq = rt_mq_create("tcp_mq", sizeof(S_MSG), 1, RT_IPC_FLAG_FIFO);
if (mq == RT_NULL)
{
LOG_E("create message queue failed");
return -1;
}
rt_thread_t tcp_client_thread = rt_thread_create("tcp_client", tcp_client_thread_entry, RT_NULL, 2048, 10, 10);
if (tcp_client_thread == RT_NULL)
{
LOG_E("create thread failed");
return -1;
}
rt_thread_startup(tcp_client_thread);
return 0;
}
INIT_APP_EXPORT(tcp_client_init);

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1261

    瀏覽量

    39840
  • TCP通信
    +關(guān)注

    關(guān)注

    0

    文章

    146

    瀏覽量

    4200
收藏 人收藏

    評論

    相關(guān)推薦

    一種簡單的可控硅好壞判斷方法

    一種簡單的可控硅好壞判斷方法
    發(fā)表于 07-28 08:17 ?6265次閱讀

    一種很簡單的增量調(diào)制(DM)編碼

    、CCITT μ律、GSM 6.10、PCM、ADPCM。本文將介紹一種很簡單的增量調(diào)制(DM)編碼方式。 DM編解碼 DM(Delta Modulation)編碼的原理很簡單,信號處理的學(xué)習(xí)者對這個
    的頭像 發(fā)表于 12-31 12:17 ?7698次閱讀

    一種簡單的OpenHarmony環(huán)境搭建方法

    本文介紹一種簡單的OpenHarmony環(huán)境搭建方法。
    的頭像 發(fā)表于 03-14 13:58 ?3366次閱讀
    <b class='flag-5'>一種</b><b class='flag-5'>簡單</b>的OpenHarmony環(huán)境搭建<b class='flag-5'>方法</b>

    一種簡單的逆變器輸出直流分量消除方法

    逆變器輸出直流分量會對逆變器本身和交流負(fù)載產(chǎn)生不利影響,必須消除直流分量來保障逆變器的可靠運(yùn)行。提出了一種簡單的消除輸出直流分量的方法,并在理論分析的基礎(chǔ)上,通過對1臺220V、1 kW的逆變器系統(tǒng)
    發(fā)表于 12-27 11:20

    介紹一種快速簡單創(chuàng)建TCP、UDP服務(wù)平臺的方法

    有時候我們需要做項(xiàng)目的時候,需要硬件通過TCP、UDP協(xié)議和服務(wù)器交互。我介紹一種基于“nodejs”的方法,用幾行代碼就可以創(chuàng)建TCP服務(wù)和UDP服務(wù),完成硬件客戶端和服務(wù)端的交互。
    發(fā)表于 05-24 00:32

    一種節(jié)省能源的簡單方法

    一種節(jié)省能源的簡單方法是在晚上關(guān)閉Mac。與活動,空閑或睡眠的Mac相比,關(guān)機(jī)的Mac所消耗的能源更少。對于運(yùn)行大量Mac的組織,應(yīng)優(yōu)先考慮整夜關(guān)機(jī)。反對在夜間關(guān)閉的個常見論點(diǎn)是關(guān)
    發(fā)表于 12-29 08:20

    介紹一種簡單的數(shù)據(jù)解析方法

    JSON。? 下面我將介紹一種簡單的數(shù)據(jù)解析方法,通過編寫函數(shù),將字符串解析取得目標(biāo)數(shù)據(jù)。解析字符型數(shù)據(jù)函數(shù)原型/*** @brief從段字符串中解析期望的字符串* @parampB
    發(fā)表于 02-28 06:15

    有沒有一種方法可以發(fā)送和接收不會阻塞的Http數(shù)據(jù)單片機(jī)?

    狀態(tài),是否需要重新啟動,或者是否有新的固件更新,或者其他。這切都按預(yù)期工作,并按照我的期望進(jìn)行操作。我遇到的問題是,每當(dāng)節(jié)點(diǎn)需要將該 ping 發(fā)送到服務(wù)器時,LED 字符串會短暫凍結(jié)(大約秒鐘)。所以我的問題是,有沒有
    發(fā)表于 05-15 07:40

    是否有一種簡單方法將esp連接到openhab并發(fā)送特殊命令?

    嗨, (首先抱歉我的英語不好) 個月以來我直在玩 ESP,我真的很喜歡它! 但現(xiàn)在我想更進(jìn)步,將 ESP 連接到 Openhab 并控制燈、RGB-LED 等。 所以我的問題:是否有一種
    發(fā)表于 05-24 08:14

    如何使用中斷的快速/非阻塞SPI?

    我正在尋找一種幾乎連續(xù)發(fā)送 SPI 數(shù)據(jù)而阻塞 CPU 的方法。我通常使用 PlatformIO / Arduino SDK 進(jìn)行開發(fā),其
    發(fā)表于 05-29 08:01

    TD-HSUPA系統(tǒng)的TCP優(yōu)化方法

    本文提出了一種TD-HSUPA系統(tǒng)的TCP優(yōu)化方法:利用無線網(wǎng)絡(luò)控制器RNC(Radio Network Controller)解析TCP連接鏈路上服務(wù)器的反饋包信息。本
    發(fā)表于 08-03 11:30 ?2806次閱讀
    TD-HSUPA系統(tǒng)的<b class='flag-5'>TCP</b>優(yōu)化<b class='flag-5'>方法</b>

    一種簡單背景下的快速邊緣檢測方法_周恩明

    一種簡單背景下的快速邊緣檢測方法_周恩明
    發(fā)表于 03-19 11:46 ?0次下載

    MSP430異步通信(發(fā)送)阻塞CPU,含注釋

    直接上代碼/*************************發(fā)送數(shù)據(jù)幀的程序利用發(fā)送中斷,發(fā)送過程阻塞CPU繼續(xù)執(zhí)行后續(xù)代碼Author
    發(fā)表于 12-14 19:02 ?0次下載
    MSP430異步通信(<b class='flag-5'>發(fā)送</b>)<b class='flag-5'>不</b><b class='flag-5'>阻塞</b>CPU,含注釋

    一種以硬件語言向Arduino發(fā)送消息的方法

    電子發(fā)燒友網(wǎng)站提供《一種以硬件語言向Arduino發(fā)送消息的方法.zip》資料免費(fèi)下載
    發(fā)表于 11-02 16:14 ?0次下載
    <b class='flag-5'>一種</b>以硬件語言向Arduino<b class='flag-5'>發(fā)送</b>消息的<b class='flag-5'>方法</b>

    一種簡單高效配置FPGA的方法

    本文描述了一種簡單高效配置FPGA的方法,該方法利用微處理器從串行外圍接口(SPI)閃存配置FPGA設(shè)備。這種方法減少了硬件組件、板空間和成
    的頭像 發(fā)表于 10-24 14:57 ?256次閱讀
    <b class='flag-5'>一種</b><b class='flag-5'>簡單</b>高效配置FPGA的<b class='flag-5'>方法</b>