IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> ESP8266 TCP客户端代码(自动连接断开识别) -> 正文阅读

[网络协议]ESP8266 TCP客户端代码(自动连接断开识别)

user_socket.c

#include "user_socket.h"



//===================================================================
//							变量定义
//===================================================================
int tcp_fd = -1;




/********************************************************************
 *@brief	发送TCP数据
 *@param[in] buffer
 *@param[in] size
 *@return	 <0失败	成功时返回已发送的长度
 *******************************************************************/
int user_socket_tcp_send(const void *buffer, size_t size)
{
	if(tcp_fd < 0 || buffer == NULL || size <= 0)
	{
		return -1;
	}

	return send(tcp_fd,buffer,size,0);
}


/********************************************************************
 *@brief	TCP连接
 *@param[in] none
 *@return	 <0失败	成功时返回fd
 *******************************************************************/
int user_socket_tcp_connect(void)
{
	int fd;
	int tmp;
	struct sockaddr_in addr;
	memset((char*)&addr,0,sizeof(addr));

	addr.sin_family 	 = AF_INET;
	addr.sin_port 		 = htons(USER_TCP_PORT);
	addr.sin_addr.s_addr = inet_addr(USER_TCP_IP);

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if(fd < 0)
	{
		printf("tcp socket fail\n");
		return -1;
	}

	//开启keepalive属性
	tmp = 1;
	if(setsockopt(fd, SOL_SOCKET,SO_KEEPALIVE,&tmp,sizeof(tmp)) < 0)
	{
		printf("tcp set SO_KEEPALIVE fail\n");
	}

	//如该连接在10秒内没有任何数据往来,则进行探测
	tmp = 10;
	if(setsockopt(fd, IPPROTO_TCP,TCP_KEEPIDLE,&tmp,sizeof(tmp))<0)
	{
		printf("tcp set TCP_KEEPIDLE fail\n");
	}

	//探测时发包的时间间隔为2秒
	tmp = 2;
	if(setsockopt(fd, IPPROTO_TCP,TCP_KEEPINTVL,&tmp,sizeof(tmp))<0)
	{
		printf("tcp set TCP_KEEPINTVL fail\n");
	}

	//探测尝试的次数.如果第1次探测包就收到响应了,则后几次的不再发
	tmp = 3;
	if(setsockopt(fd, IPPROTO_TCP,TCP_KEEPCNT,&tmp,sizeof(tmp))<0)
	{
		printf("tcp set TCP_KEEPCNT fail\n");
	}

	//开始连接tcp
	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		close(fd);
		printf("tcp connect fail\n");
		return -1;
	}

	printf("tcp connect ok!\n");

	return fd;
}



/********************************************************************
 *@brief	TCP任务
 *@param[in] pvParameters
 *@return	 none
 *******************************************************************/
static void user_socket_tcp_task(void *pvParameters)
{
	printf("%s\n",__func__);

	//申请TCP接收buff内存
	uint8_t *tcp_rx_buff = NULL;
	if((tcp_rx_buff = (uint8_t*)os_malloc(USER_TCP_RX_BUFF_MAX)) == NULL)
	{
		printf("failed to allocate memory\r\n");
		goto	user_socket_tcp_task_exit;
	}


	tcp_fd = -1;
	int    ufd,maxfd;
	fd_set rset;
	struct timeval 		timeout;
	struct sockaddr_in  addr;
	memset((char*)&addr,0,sizeof(addr));

	addr.sin_family 	 = AF_INET;
	addr.sin_port   	 = htons(10000);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

	ufd = socket(AF_INET, SOCK_DGRAM, 0);

	if(ufd < 0)
	{
		printf("create udp socket fail\n");
	}

	bind(ufd, (struct sockaddr*)&addr, sizeof(addr));

	maxfd = ufd;

	//清空socket集合
	FD_ZERO(&rset);


	while(1)
	{
		//wifi没有连接成功,或者还没有获取到IP
		if(wifi_station_get_connect_status() != STATION_GOT_IP)
		{
			vTaskDelay(100/portTICK_RATE_MS);
			continue;
		}

		//是否socket没有连接
		if(tcp_fd < 0)
		{
			//尝试连接socket
			if((tcp_fd = user_socket_tcp_connect()) < 0)
			{
				vTaskDelay(500/portTICK_RATE_MS);
				continue;
			}
		}

		maxfd = ufd;
		if(maxfd < tcp_fd)
		{
			maxfd = tcp_fd;
		}

		//清空socket集合
		FD_ZERO(&rset);

		if(tcp_fd >= 0)
		{
			//加入已连接的socket到集合
			FD_SET(tcp_fd,&rset);
		}

		FD_SET(ufd,&rset);

		timeout.tv_sec  = 3;	//秒
		timeout.tv_usec = 0;	//微秒
		//在此函数最大等待timeout.tv_sec秒,如果有收到数据就立即退出此函数。
		if(select(maxfd+1, &rset, NULL, NULL, &timeout) <= 0)
		{
			continue;
		}


		//检查tcp_fd是否在这个集合里面
		if (FD_ISSET(tcp_fd, &rset))
		{
			int read_length;

			//TCP接收数据处理
			if((read_length = recv(tcp_fd,tcp_rx_buff,USER_TCP_RX_BUFF_MAX,0)) > 0)
			{
				printf("fd read_buff data bytes:%d\r\n",read_length);
				USER_LOG_HEXDUMP(tcp_rx_buff,read_length);
			}
			else
			{
				close(tcp_fd);
				tcp_fd = -1;

				printf("tcp disconnectd!\r\n");
			}
		}
		//检查ufd是否在这个集合里面
		else if(FD_ISSET(ufd,&rset))
		{
			int alen = sizeof(struct sockaddr_in);

			int read_length;
			if((read_length=recvfrom(ufd,tcp_rx_buff,USER_TCP_RX_BUFF_MAX,0,(struct sockaddr*)&addr,(socklen_t*)&alen)) > 0)
			{
				printf("ufd read_buff data bytes:%d\r\n",read_length);
				USER_LOG_HEXDUMP(tcp_rx_buff,read_length);
			}
		}
	}

user_socket_tcp_task_exit:
	if(tcp_rx_buff != NULL)  aos_free(tcp_rx_buff);

	vTaskDelete(NULL);
}





/********************************************************************
 *@brief	 tcp初始化
 *@param[in] none
 *@return	 none
 *******************************************************************/
void user_socket_tcp_init(void)
{
    xTaskCreate(user_socket_tcp_task, "", 256, NULL, 4, NULL);
}










user_socket.h

#ifndef __USER_SOCKET_H__
#define __USER_SOCKET_H__

#include "esp_common.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lwip/sockets.h"


//===================================================================
//							常量定义
//===================================================================
#define	USER_TCP_IP					"192.168.46.108"
#define	USER_TCP_PORT				8080
#define USER_TCP_RX_BUFF_MAX		256





//===================================================================
//							函数声明
//===================================================================
static void user_socket_tcp_task(void *pvParameters);
int user_socket_tcp_send(const void *buffer, size_t size);
void user_socket_tcp_init(void);
#endif

使用说明:

? ? ? ? 1、在user_init函数中调用user_socket_tcp_init创建tcp任务

? ? ? ? 2、WIFI连接成功之后,会自动进行TCP连接,tcp连接成功时打印 tcp connect ok!。tcp断开连接时打印tcp disconnectd!。收到tcp数据时打印fd read_buff data bytes。

? ? ? ? 3、’用户发送tcp数据时调用user_socket_tcp_send

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:48:48  更:2021-08-21 15:49:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 18:09:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码