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

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

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

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

冬至子 ? 來(lái)源:BruceTan ? 作者:BruceTan ? 2023-09-20 14:23 ? 次閱讀

背景介紹

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

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

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

代碼實(shí)現(xiàn)如下,當(dāng)采集到數(shù)據(jù)的時(shí)候,只需要調(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)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1291

    瀏覽量

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

    關(guān)注

    0

    文章

    146

    瀏覽量

    4224
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    一種簡(jiǎn)單的可控硅好壞判斷方法

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

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

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

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

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

    一種簡(jiǎn)單的逆變器輸出直流分量消除方法

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

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

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

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

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

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

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

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

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

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

    嗨, (首先抱歉我的英語(yǔ)不好) 個(gè)月以來(lái)我直在玩 ESP,我真的很喜歡它! 但現(xiàn)在我想更進(jìn)步,將 ESP 連接到 Openhab 并控制燈、RGB-LED 等。 所以我的問(wèn)題:是否有一種
    發(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ú)線網(wǎng)絡(luò)控制器RNC(Radio Network Controller)解析TCP連接鏈路上服務(wù)器的反饋包信息。本
    發(fā)表于 08-03 11:30 ?2827次閱讀
    TD-HSUPA系統(tǒng)的<b class='flag-5'>TCP</b>優(yōu)化<b class='flag-5'>方法</b>

    一種簡(jiǎn)單背景下的快速邊緣檢測(cè)方法_周恩明

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

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

    直接上代碼/*************************發(fā)送數(shù)據(jù)幀的程序利用發(fā)送中斷,發(fā)送過(guò)程阻塞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,含注釋

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

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

    一種簡(jiǎn)單高效配置FPGA的方法

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