【STM32F407+CUBEMX+FreeRTOS+lwIP之TCP记录】

STM32F407+CUBEMX+FreeRTOS+lwIP之TCP记录

注意

如果连接失败,建议关一下代理软件。

配置方面可以参考一下上一篇UDP的文章
STM32F407+CUBEMX+FreeRTOS+lwIP之UDP记录

TCP client(socket)

c 复制代码
#define LWIP_DEMO_PORT 8081
#define LWIP_DEMO_RX_BUFSIZE         200    /* 最大接收数据长度 */
#define IP_ADDR   "192.168.123.92"/*client 服务端ip*/
osThreadId_t socket_tcp_TaskHandle;
const osThreadAttr_t socket_tcp_Task_attributes = {
  .name = "socket_tcp_Task",
  .stack_size = 128 * 8,
  .priority = (osPriority_t) (osPriorityNormal-9),
};
void Start_socket_tcp_Task(void *argument);
/* 数据发送标志位 */
uint8_t g_lwip_send_flag;
int g_lwip_sock = -1;
int g_lwip_connect_state = 0;
c 复制代码
socket_tcp_TaskHandle = osThreadNew(Start_socket_tcp_Task, NULL, &socket_tcp_Task_attributes);

lwip初始化后加点延时再连接

c 复制代码
void Start_socket_tcp_Task(void *argument){	
	vTaskDelay(1000);
	vTaskDelay(1000);
	vTaskDelay(1000);
	
	struct sockaddr_in atk_client_addr;
    err_t err;
	char g_lwip_demo_sendbuf[] = "ALIENTEK DATA \r\n";
	g_lwip_connect_state = 0;
	/*tcp client*/
	atk_client_addr.sin_family = AF_INET;                   /* 表示IPv4网络协议 */
	atk_client_addr.sin_port = htons(LWIP_DEMO_PORT);       /* 端口号 */
	atk_client_addr.sin_addr.s_addr = inet_addr(IP_ADDR);   /* 远程IP地址 */
	/**/
	g_lwip_sock = socket(AF_INET, SOCK_STREAM, 0);          /* 可靠数据流交付服务既是TCP协议 */
	if(g_lwip_sock<0){
		printf("socket failed\n");
	}
	printf("g_lwip_sock %d\n",g_lwip_sock);
	memset(&(atk_client_addr.sin_zero), 0, sizeof(atk_client_addr.sin_zero));
	/*tcp client*/
sock_start:	
	
	/* 连接远程IP地址 */
	err = connect(g_lwip_sock, (struct sockaddr *)&atk_client_addr, sizeof(struct sockaddr));
	/**/
	if (err == -1)
	{
		printf("连接失败\r\n");
		g_lwip_sock = -1;
		closesocket(g_lwip_sock);
		vTaskDelay(10);
		goto sock_start;
	}

	printf("连接成功\r\n");
	g_lwip_connect_state = 1;
	g_lwip_send_flag=1;
	 while (1)
	{
		if(((g_lwip_send_flag) == 1) && (g_lwip_connect_state == 1)) /* 有数据要发送 */
		{
			err = write(g_lwip_sock, g_lwip_demo_sendbuf, sizeof(g_lwip_demo_sendbuf));
			
			if (err < 0)
			{
				break;
			}
			g_lwip_send_flag=0;
		}
		vTaskDelay(10);
	}
c 复制代码
void lwip_recv_Task(void *argument){
	BaseType_t lwip_err;
	
	struct sockaddr_in sender;
    int sender_len = sizeof(sender);
	while(1){
		#ifdef lwip_socket_udp
		memset(g_lwip_demo_recvbuf, 0, sizeof(g_lwip_demo_recvbuf));
//		recv(sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0);
		recvfrom(sock_fd, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0,(struct sockaddr*)&sender,(socklen_t *)&sender_len);
		#endif
		#ifdef lwip_socket_tcp
		recvfrom(g_lwip_sock, (void *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0,(struct sockaddr*)&sender,(socklen_t *)&sender_len);
//		recv(g_lwip_sock,g_lwip_demo_recvbuf,
//                                 LWIP_DEMO_RX_BUFSIZE,0);
		#endif


			/*IP*/
			printf("%s %d \n", inet_ntoa(sender.sin_addr), ntohs(sender.sin_port));
			printf("%s\n",g_lwip_demo_recvbuf);
			write(g_lwip_sock, g_lwip_demo_recvbuf, 
		vTaskDelay(10);
	}
}

示例

TCP_server(socket)

c 复制代码
void Start_socket_tcp_Task(void *argument){	
	vTaskDelay(1000);
	vTaskDelay(1000);
	vTaskDelay(1000);
	
	struct sockaddr_in atk_client_addr;
    err_t err;
	char g_lwip_demo_sendbuf[] = "ALIENTEK DATA \r\n";
	
	struct sockaddr_in conn_addr;   /* 连接地址 */
	socklen_t addr_len;             /* 地址长度 */
	int length;
	int g_sock_conn;
		
	g_lwip_connect_state = 0;
	g_lwip_sock = socket(AF_INET, SOCK_STREAM, 0);          /* 可靠数据流交付服务既是TCP协议 */
/*tcp server*/
	memset(&atk_client_addr, 0, sizeof(atk_client_addr));        /* 将服务器地址清空 */
	atk_client_addr.sin_family = AF_INET;                   /* 表示IPv4网络协议 */
	atk_client_addr.sin_port = htons(LWIP_DEMO_PORT);       /* 端口号 */
	atk_client_addr.sin_addr.s_addr = htonl(INADDR_ANY);;   /* 远程IP地址 */
	err = bind(g_lwip_sock, (struct sockaddr *)&atk_client_addr, sizeof(atk_client_addr)); /* 建立绑定 */
	printf("err1 %d\n",err);
	if (err < 0)                /* 如果绑定失败则关闭套接字 */
    {
		printf("bind failed\n");
        closesocket(g_lwip_sock);   /* 关闭套接字 */
    }
    err = listen(g_lwip_sock, 4);   /* 监听连接请求 */
    if (err < 0)                /* 如果监听失败则关闭套接字 */
    {
		printf("listen failed\n");
        closesocket(g_lwip_sock);   /* 关闭套接字 */
    }
	printf("err2 %d\n",err);
/*tcp server*/
	printf("tcp server \n");
	while(1){
		printf("while 1 \n");
		addr_len = sizeof(struct sockaddr_in); /* 将链接地址赋值给addr_len */
		printf("addr_len \n");
		g_sock_conn = accept(g_lwip_sock, (struct sockaddr *)&conn_addr, &addr_len); /* 对监听到的请求进行连接,状态赋值给g_sock_conn */
		printf("g_sock_conn \n");
		if (g_sock_conn < 0) /* 状态小于0代表连接故障,此时关闭套接字 */
		{
			closesocket(g_lwip_sock);
			printf("closesocket \n");
		}
		else 
		{
			g_lwip_connect_state = 1;
		}
	
		while(1){
			printf("while 2 \n");
			memset(g_lwip_demo_recvbuf,0,LWIP_DEMO_RX_BUFSIZE);
			length = recv(g_sock_conn, (unsigned int *)g_lwip_demo_recvbuf, sizeof(g_lwip_demo_recvbuf), 0); /* 将收到的数据放到接收Buff */
			
			if (length <= 0)
			{
				goto atk_exit;
			}
			
            printf("%s",g_lwip_demo_recvbuf);
			
			vTaskDelay(10);
//			lwip_err = xQueueSend(g_display_queue,&g_lwip_demo_recvbuf,0);

//			if (lwip_err == errQUEUE_FULL)
//			{
//				printf("队列Key_Queue已满,数据发送失败!\r\n");
//			}
		}
	atk_exit:
		if (g_sock_conn >= 0)
		{          
			closesocket(g_sock_conn);
			g_sock_conn = -1;
		}
		printf("atk_exit \n");
	}

效果

相关推荐
嵌新程3 小时前
day06(单片机高级)PCB设计
单片机·嵌入式硬件·pcb
stm 学习ing3 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
傻啦嘿哟4 小时前
代理IP在后端开发中的应用与后端工程师的角色
网络·网络协议·tcp/ip
Estar.Lee6 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
LateBloomer7777 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
友友马7 小时前
『 Linux 』网络层 - IP协议(一)
linux·网络·tcp/ip
wenchm7 小时前
细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
stm32·单片机·嵌入式硬件
电子工程师UP学堂8 小时前
电子应用设计方案-16:智能闹钟系统方案设计
单片机·嵌入式硬件
飞凌嵌入式9 小时前
飞凌嵌入式T113-i开发板RISC-V核的实时应用方案
人工智能·嵌入式硬件·嵌入式·risc-v·飞凌嵌入式