背景介紹
最近在做一個(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);
-
RT-Thread
+關(guān)注
關(guān)注
31文章
1305瀏覽量
40391 -
TCP通信
+關(guān)注
關(guān)注
0文章
146瀏覽量
4292
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
一種很簡(jiǎn)單的增量調(diào)制(DM)編碼
一種簡(jiǎn)單的逆變器輸出直流分量消除方法
介紹一種快速簡(jiǎn)單創(chuàng)建TCP、UDP服務(wù)平臺(tái)的方法
一種節(jié)省能源的簡(jiǎn)單方法
介紹一種簡(jiǎn)單的數(shù)據(jù)解析方法
有沒(méi)有一種方法可以發(fā)送和接收不會(huì)阻塞的Http數(shù)據(jù)單片機(jī)?
是否有一種簡(jiǎn)單的方法將esp連接到openhab并發(fā)送特殊命令?
如何使用中斷的快速/非阻塞SPI?
TD-HSUPA系統(tǒng)的TCP優(yōu)化方法
![TD-HSUPA系統(tǒng)的<b class='flag-5'>TCP</b>優(yōu)化<b class='flag-5'>方法</b>](https://file1.elecfans.com//web2/M00/A5/F3/wKgZomUMOvKAdROmAAAb1jok7-o815.gif)
MSP430異步通信(發(fā)送)不阻塞CPU,含注釋
![MSP430異步通信(<b class='flag-5'>發(fā)送</b>)<b class='flag-5'>不</b><b class='flag-5'>阻塞</b>CPU,含注釋](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
一種以硬件語(yǔ)言向Arduino發(fā)送消息的方法
![<b class='flag-5'>一種</b>以硬件語(yǔ)言向Arduino<b class='flag-5'>發(fā)送</b>消息的<b class='flag-5'>方法</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
一種簡(jiǎn)單高效配置FPGA的方法
![<b class='flag-5'>一種</b><b class='flag-5'>簡(jiǎn)單</b>高效配置FPGA的<b class='flag-5'>方法</b>](https://file1.elecfans.com/web2/M00/0A/1C/wKgZomcZ7-WAIjnBAAINroizvyU375.png)
評(píng)論