运行 STM32 上的 TCP 服务器和 UDP 客户端
Running TCP Server and UDP Client on a STM32
我正在尝试在 STM32 Nucleo F746ZG 上同时 运行 TCP 服务器和 UDP 客户端。我正在使用 freeRTOS 和 LWIP 库,我在 运行 同时使用两种网络技术(TCP 和 UDP)时遇到了麻烦。然而,它们独立工作得很好。不可能同时 运行 或者我的代码有问题?
这是我实现 TCP 服务器的方式:
static void tcp_thread(void *arg)
{
struct_out *qstruct;
err_t err, recv_err;
struct netconn *conn;
struct netbuf *inbuf;
struct netconn *newconn;
struct_sock *arg_sock;
arg_sock = (struct_sock*) arg;
conn = arg_sock->conn;
u16_t buflen;
char* buf;
char* str2;
int ret;
for(;;)
{
err = netconn_accept(conn, &newconn);
if (err == ERR_OK)
{
for(;;)
{
recv_err = netconn_recv(newconn, &inbuf); //Receive data
if (recv_err == ERR_OK)
{
netbuf_data(inbuf, (void**)&buf, &buflen); //Get the data
if((buf[0]==0x0D)||(buf[0]==0x0A))//Compruebo si es un salto de
linea
{
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
continue;
}
//qstruct = osMailAlloc(strout_Queue, osWaitForever);
//qstruct->y_pos = arg_sock->y_pos;
strncpy(str_buf,buf,buflen);
str_buf[buflen]=0;
//sprintf(qstruct->str,"%-20s", str_buf);
osMailPut(strout_Queue, qstruct);
osMailFree(strout_Queue, qstruct);
//Salto de linea para a la hora de imprimir dejar espacio y que no
se peguen los mensajes
str_buf[buflen] = '\r';
str_buf[buflen+1] = '\n';
strcpy(str2, "hi");
ret = strncmp(str_buf, str2, 4);
if(ret == 0) {
netconn_write(newconn, str_buf, buflen+2, NETCONN_COPY);
//Escribe y si lo quito no hay ACK de llegada del paquete
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
} else {
netconn_write(newconn, "recived", 4, NETCONN_COPY);
//Escribe y
si lo quito no hay ACK de llegada del paquete
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
}
}
else
{
netbuf_delete(inbuf);
netconn_close(newconn);
break;
}
}
}
else
{
osDelay(1);
}
}
void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
struct netconn *conn;
err_t err;
//sock01.y_pos = 60;
//sock02.y_pos = 180;
conn = netconn_new(NETCONN_TCP);
if(conn!=NULL)
{
sock01.conn = conn;
sock02.conn = conn;
err = netconn_bind(conn, NULL, 80);
if (err == ERR_OK)
{
netconn_listen(conn);
sys_thread_new("tcp_thread1", tcp_thread, (void*)&sock01,
DEFAULT_THREAD_STACKSIZE, osPriorityNormal );
sys_thread_new("tcp_thread2", tcp_thread, (void*)&sock02,
DEFAULT_THREAD_STACKSIZE, osPriorityNormal );
}
else
{
netconn_delete(conn);
}
}
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END 5 */
}
这是 UDP 客户端:
void udp_client_connect(void)
{
ip_addr_t DestIPaddr;
err_t err;
upcb = udp_new();
if (upcb!=NULL)
{
IP4_ADDR(&DestIPaddr, 192, 168, 1, 150);
upcb->local_port = 1555;
err= udp_connect(upcb, &DestIPaddr, 52709);
if (err == ERR_OK)
{
udp_recv(upcb, udp_receive_callback, NULL);
}
}
}
谢谢队友!!
我通过不使用 FreeRTOS 库解决了这个问题,因为如果你想实现它,你只能同时执行一项任务。我推荐你,看看你的电路板的 ST Microelectronics 教程,你可以在下面找到它 link:
在这里您可以找到一些仅使用 LWIP 库的 UDP 和 TCP(服务器和客户端)示例,这样更容易。
希望能解决您的问题 ;)
我正在尝试在 STM32 Nucleo F746ZG 上同时 运行 TCP 服务器和 UDP 客户端。我正在使用 freeRTOS 和 LWIP 库,我在 运行 同时使用两种网络技术(TCP 和 UDP)时遇到了麻烦。然而,它们独立工作得很好。不可能同时 运行 或者我的代码有问题?
这是我实现 TCP 服务器的方式:
static void tcp_thread(void *arg)
{
struct_out *qstruct;
err_t err, recv_err;
struct netconn *conn;
struct netbuf *inbuf;
struct netconn *newconn;
struct_sock *arg_sock;
arg_sock = (struct_sock*) arg;
conn = arg_sock->conn;
u16_t buflen;
char* buf;
char* str2;
int ret;
for(;;)
{
err = netconn_accept(conn, &newconn);
if (err == ERR_OK)
{
for(;;)
{
recv_err = netconn_recv(newconn, &inbuf); //Receive data
if (recv_err == ERR_OK)
{
netbuf_data(inbuf, (void**)&buf, &buflen); //Get the data
if((buf[0]==0x0D)||(buf[0]==0x0A))//Compruebo si es un salto de
linea
{
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
continue;
}
//qstruct = osMailAlloc(strout_Queue, osWaitForever);
//qstruct->y_pos = arg_sock->y_pos;
strncpy(str_buf,buf,buflen);
str_buf[buflen]=0;
//sprintf(qstruct->str,"%-20s", str_buf);
osMailPut(strout_Queue, qstruct);
osMailFree(strout_Queue, qstruct);
//Salto de linea para a la hora de imprimir dejar espacio y que no
se peguen los mensajes
str_buf[buflen] = '\r';
str_buf[buflen+1] = '\n';
strcpy(str2, "hi");
ret = strncmp(str_buf, str2, 4);
if(ret == 0) {
netconn_write(newconn, str_buf, buflen+2, NETCONN_COPY);
//Escribe y si lo quito no hay ACK de llegada del paquete
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
} else {
netconn_write(newconn, "recived", 4, NETCONN_COPY);
//Escribe y
si lo quito no hay ACK de llegada del paquete
netbuf_delete(inbuf); //Limpia el buffer de entrada de datos
}
}
else
{
netbuf_delete(inbuf);
netconn_close(newconn);
break;
}
}
}
else
{
osDelay(1);
}
}
void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
struct netconn *conn;
err_t err;
//sock01.y_pos = 60;
//sock02.y_pos = 180;
conn = netconn_new(NETCONN_TCP);
if(conn!=NULL)
{
sock01.conn = conn;
sock02.conn = conn;
err = netconn_bind(conn, NULL, 80);
if (err == ERR_OK)
{
netconn_listen(conn);
sys_thread_new("tcp_thread1", tcp_thread, (void*)&sock01,
DEFAULT_THREAD_STACKSIZE, osPriorityNormal );
sys_thread_new("tcp_thread2", tcp_thread, (void*)&sock02,
DEFAULT_THREAD_STACKSIZE, osPriorityNormal );
}
else
{
netconn_delete(conn);
}
}
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END 5 */
}
这是 UDP 客户端:
void udp_client_connect(void)
{
ip_addr_t DestIPaddr;
err_t err;
upcb = udp_new();
if (upcb!=NULL)
{
IP4_ADDR(&DestIPaddr, 192, 168, 1, 150);
upcb->local_port = 1555;
err= udp_connect(upcb, &DestIPaddr, 52709);
if (err == ERR_OK)
{
udp_recv(upcb, udp_receive_callback, NULL);
}
}
}
谢谢队友!!
我通过不使用 FreeRTOS 库解决了这个问题,因为如果你想实现它,你只能同时执行一项任务。我推荐你,看看你的电路板的 ST Microelectronics 教程,你可以在下面找到它 link:
在这里您可以找到一些仅使用 LWIP 库的 UDP 和 TCP(服务器和客户端)示例,这样更容易。
希望能解决您的问题 ;)