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

发布于:2024-04-30 ⋅ 阅读:(29) ⋅ 点赞:(0)

STM32F407+CUBEMX+FreeRTOS+lwIP之TCP记录

注意

如果连接失败,建议关一下代理软件。
配置方面可以参考一下上一篇UDP的文章
STM32F407+CUBEMX+FreeRTOS+lwIP之UDP记录

TCP client(socket)

#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;
socket_tcp_TaskHandle = osThreadNew(Start_socket_tcp_Task, NULL, &socket_tcp_Task_attributes);

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

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);
	}
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)

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");
	}

效果

在这里插入图片描述