提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
解决TCP连接过程中意外中断的情况,暂无考虑长时间网络断掉。如果长时间网络断掉,建议起一个定时器来做定时连接
一、具备的基础
你要想看懂这个代码,首先你得了解一下uloop这个框架。网上资料很多,当然这个框架也不是那么完善,有一定的坑在,还是得需要多写写。其次,你得简单了解一下usock,不用那么细致。最后,你有个开发板,或者你装在ubunt上测试。
二、代码展示
代码如下:
/*
* 作者:笨笨熊
* 日期:2021/12/20
* 用途:
* 该程序主要是基于usock编程的客户端
* 主要是测试程序的断线重连,适合于TCP协议连接
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <asm/ioctl.h>
#include <sys/socket.h>
#include <libubox/usock.h>
#include "libubox/uloop.h"
#include "tool.h"
#define SERVER_IP "172.16.5.14"
#define SERVER_PORD "8888"
struct uloop_fd c_fd; /*客户端接收数据句柄*/
struct uloop_timeout c_send; /*客户端定时发送句柄*/
char recv_buf[64]; /*数据接收缓冲区*/
/*重连函数*/
static int reconnect()
{
int type = USOCK_TCP | USOCK_NOCLOEXEC | USOCK_IPV4ONLY;
c_fd.fd = usock(type, SERVER_IP, SERVER_PORD); /* create a linker socket*/
if (c_fd.fd < 0)
{
perror("usock error");
return -1;
}
uloop_fd_add(&c_fd, ULOOP_READ);
uloop_timeout_set(&c_send, 2000); //2s发一次
return 0;
}
/*接收服务器数据*/
int clinet_recv(struct uloop_fd *sock, unsigned int events)
{
int rev_len;
rev_len = read(sock->fd, recv_buf, sizeof(recv_buf));
if (rev_len > 0)
{
DEBUG_PRINT("Recv:%s Len:%d \n", recv_buf, rev_len);
memset(recv_buf, 0, sizeof(recv_buf));
write(sock->fd, "#", 1);
}
else
{
/*此时判断断开连接,进入重连*/
DEBUG_PRINT("Recv failed\n");
goto error;
}
return 0;
error:
if (sock->fd)
{
uloop_fd_delete(sock);
close(sock->fd);
sock->fd = -1;
DEBUG_PRINT("Close client fd\n");
uloop_timeout_cancel(&c_send);
if (reconnect() < 0)
{
DEBUG_PRINT("ERROR: INIT FAILED\n");
}
else
{
DEBUG_PRINT("CONNECT SUCCESS!!!\n");
}
}
return 0;
}
/*定时向服务器发送数据*/
static void c_send_timer(struct uloop_timeout *timer)
{
int ret;
DEBUG_PRINT("hello\n");
ret = write(c_fd.fd, "hello", 5);
if (ret < 0)
{
uloop_timeout_cancel(timer);
DEBUG_PRINT("Cancel send \n");
}
uloop_timeout_set(&c_send, 2000); //2s发一次
}
static int client_init()
{
int type = USOCK_TCP | USOCK_NOCLOEXEC | USOCK_IPV4ONLY;
c_fd.fd = usock(type, SERVER_IP, SERVER_PORD); /* create a linker socket*/
if (c_fd.fd < 0)
{
perror("usock");
return -1;
}
/*客户端接收回调绑定*/
c_fd.cb = clinet_recv;
uloop_fd_add(&c_fd, ULOOP_READ);
/*定时发送回调绑定*/
c_send.cb = c_send_timer;
uloop_timeout_set(&c_send, 2000); //2s发一次
return 0;
}
int main()
{
uloop_init();
/*客户端初始化*/
if (client_init() < 0)
{
DEBUG_PRINT("ERROR: INIT FAILED\n");
}
else
{
DEBUG_PRINT("CONNECT SUCCESS!!!\n");
}
uloop_run();
close(c_fd.fd);
uloop_done();
return 0;
}
2.测试结果
客户端状况:
服务端状况
总结
没有太过细致的去帮大家分析一下,注释都已经写了。大家慢慢看吧。有什么问题也可以提问,我会及时回复。如果写的不好,也可以跟我说。如果代码有帮到你,麻烦点一个赞吧。