背景介紹
最近在做一個功能的時候,要求將采集到的數(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);
-
RT-Thread
+關(guān)注
關(guān)注
31文章
1261瀏覽量
39840 -
TCP通信
+關(guān)注
關(guān)注
0文章
146瀏覽量
4200
發(fā)布評論請先 登錄
相關(guān)推薦
評論