STM32F407+CUBEMX+FreeRTOS+lwIP之TCP记录
- 注意
- TCP client(socket)
- 示例
- TCP_server(socket)
- 效果
注意
如果连接失败,建议关一下代理软件。
配置方面可以参考一下上一篇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");
}