0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分享一种很简单的不阻塞TCP发送方法

冬至子 来源:BruceTan 作者:BruceTan 2023-09-20 14:23 次阅读

背景介绍

最近在做一个功能的时候,要求将采集到的数据发送到TCP Server上,TCP Server有时候可能会出问题连接不上,这时候如果使用普通的TCP编程,就会造成数据采集的代码被阻塞了。

为了解决这个问题,我将TCP发送的代码使用一个单独的线程实现,数据采集的代码在另外一个线程实现,两个线程之间使用消息队列进行通信,这样既不会破坏TCP编程的基础模型,又可以实现应用代码非阻塞发送TCP数据。

代码实现

代码实现如下,当采集到数据的时候,只需要调用tcp_client_no_block_send函数发送数据即可。

#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);

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RT-Thread
    +关注

    关注

    31

    文章

    1149

    浏览量

    38909
  • TCP通信
    +关注

    关注

    0

    文章

    145

    浏览量

    4138
收藏 人收藏

    评论

    相关推荐

    一种简单的逆变器输出直流分量消除方法

    逆变器输出直流分量会对逆变器本身和交流负载产生不利影响,必须消除直流分量来保障逆变器的可靠运行。提出了一种简单的消除输出直流分量的方法,并在理论分析的基础上,通过对1台220V、1 kW的逆变器系统
    发表于 12-27 11:20

    Java线程阻塞方法大全

    ()方法,当前线程转A入阻塞状态,直到线程B运行结束,线程A才由阻塞状态转为可执行状态。以上是Java线程唤醒和阻塞的五常用
    发表于 04-02 15:42

    Verilog中阻塞赋值和非阻塞赋值的正确使用

    [table][tr][td] Verilog中有两为变量赋值的方法一种叫做连续赋值,另一种叫做过程赋值。过程赋值又分为阻塞赋值和非
    发表于 07-03 03:06

    介绍一种快速简单创建TCP、UDP服务平台的方法

    有时候我们需要做项目的时候,需要硬件通过TCP、UDP协议和服务器交互。我介绍一种基于“nodejs”的方法,用几行代码就可以创建TCP服务和UDP服务,完成硬件客户端和服务端的交互。
    发表于 05-24 00:32

    产生阻塞的主要来源是什么?

    本文按3GPP2标准讨论了阻塞问题,并指出了产生阻塞的主要来源,介绍了一种CDMA接收机测量阻塞的实用方法
    发表于 05-31 06:25

    求大佬分享一种简单易行的可编程振荡器构建方法

    本文介绍一种简单易行的可编程振荡器构建方法,其中,振荡频率和幅度可以通过使用digiPOT来彼此独立地调节。
    发表于 06-17 06:03

    基于TCP一种新的网络协议WebSocket

    开启 WebSocket 服务WebSocket 服务是网页程序、安卓 App、微信小程序等获得数据和服务的接口,是基于TCP一种新的网络协议,它实现了浏览器与服务器全双工通信。通过
    发表于 12-16 07:38

    一种节省能源的简单方法

    一种节省能源的简单方法是在晚上关闭Mac。与活动,空闲或睡眠的Mac相比,关机的Mac所消耗的能源更少。对于运行大量Mac的组织,应优先考虑整夜关机。反对在夜间关闭的个常见论点是关
    发表于 12-29 08:20

    怎样才能实现MSP430异步通信的接收与发送阻塞CPU呢

    怎样才能实现MSP430异步通信的接收与发送阻塞CPU呢?
    发表于 02-14 07:41

    介绍一种简单的数据解析方法

    JSON。​ 下面我将介绍一种简单的数据解析方法,通过编写函数,将字符串解析取得目标数据。解析字符型数据函数原型/*** @brief从段字符串中解析期望的字符串* @parampB
    发表于 02-28 06:15

    有没有一种方法可以发送和接收不会阻塞的Http数据单片机?

    状态,是否需要重新启动,或者是否有新的固件更新,或者其他。这切都按预期工作,并按照我的期望进行操作。我遇到的问题是,每当节点需要将该 ping 发送到服务器时,LED 字符串会短暂冻结(大约秒钟)。所以我的问题是,有没有
    发表于 05-15 07:40

    一种简单的报错设计,分享

    一种简单的报错设计,可在次基础上增加。 冲突 阻挡 重复 不在工位 不在岗 计时不准 范围外 强停 其它
    发表于 05-20 20:07

    是否有一种简单方法将esp连接到openhab并发送特殊命令?

    嗨, (首先抱歉我的英语不好) 个月以来我直在玩 ESP,我真的很喜欢它! 但现在我想更进步,将 ESP 连接到 Openhab 并控制灯、RGB-LED 等。 所以我的问题:是否有一种
    发表于 05-24 08:14

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

    我正在寻找一种几乎连续发送 SPI 数据而阻塞 CPU 的方法。我通常使用 PlatformIO / Arduino SDK 进行开发,其
    发表于 05-29 08:01

    基站阻塞和基站失步的概念区分及处理方法

    本文简单介绍了基站阻塞和基站失步两个不同的概念,分析了两者产生的原因,同时还详细介绍了如何处理基站阻塞和基站失步问题的一些方法。基站阻塞和基
    发表于 08-01 16:16 17次下载