STM32H750B-DK与Python TCP客户端连接失败问题求助
问题:STM32 TCP Server与Python客户端连接异常排查
我尝试通过TCP从STM32H750B-DK发送字符串到Python程序并打印输出。STM32端作为TCP Server,Python端计划作为TCP客户端,但遇到以下问题:
- Python端绑定
0.0.0.0时,程序显示已监听,但无法和STM32建立连接 - Python端绑定STM32的IP地址
169.254.211.100时,抛出OSError: [WinError 10049]错误 - 使用Hercules工具可正常连接STM32并接收数据,特此求助问题原因及解决方法。
STM32端TCP Server代码
/* * tcpserver.c * * Created on: Apr 20, 2022 * Author: controllerstech.com */ #include "lwip/opt.h" #include "lwip/api.h" #include "lwip/sys.h" #include "tcpserver.h" #include "string.h" static struct netconn *conn, *newconn; static struct netbuf *buf; static ip_addr_t *addr; static unsigned short port; char msg[100]; char smsg[200]; char b[10] = {'0'}; /**** Send RESPONSE every time the client sends some data ******/ static void tcp_thread(void *arg) { err_t err, accept_err, recv_error; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); if (conn!=NULL) { /* Bind connection to the port number 7. */ err = netconn_bind(conn, IP_ADDR_ANY, 146); if (err == ERR_OK) { /* Tell connection to go into listening mode. */ netconn_listen(conn); while (1) { /* Grab new connection. */ accept_err = netconn_accept(conn, &newconn); /* Process the new connection. */ if (accept_err == ERR_OK) { /* receive the data from the client */ while (netconn_recv(newconn, &buf) == ERR_OK) { /* Extrct the address and port in case they are required */ addr = netbuf_fromaddr(buf); // get the address of the client port = netbuf_fromport(buf); // get the Port of the client /* If there is some data remaining to be sent, the following process will continue */ do { strncpy (msg, buf->p->payload, buf->p->len); // get the message from the client if (msg[0]==103){ b[0] = '1'; } else{ b[0] = 'h'; } // Or modify the message received, so that we can send it back to the client int len = sprintf (smsg, "\"%s\" was sent by the Server\n", b); netconn_write(newconn, smsg, len, NETCONN_COPY); // send the message back to the client memset (msg, '\0', 100); // clear the buffer } while (netbuf_next(buf) >0); netbuf_delete(buf); } /* Close connection and discard connection identifier. */ netconn_close(newconn); netconn_delete(newconn); } } } else { netconn_delete(conn); } } } void tcpserver_init(void) { sys_thread_new("tcp_thread", tcp_thread, NULL, DEFAULT_THREAD_STACKSIZE,osPriorityNormal); }
原Python端代码(存在角色错误)
import socket SERVER_IP = "0.0.0.0" SERVER_PORT = 146 # Create a socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((SERVER_IP, SERVER_PORT)) server_socket.listen(1) print("Server listening on", SERVER_IP, "port", SERVER_PORT) while True: client_socket, client_address = server_socket.accept() print("Connection from:", client_address) data = client_socket.recv(1024) if data: received_variable = int(data.decode()) print("Received variable:", received_variable) client_socket.close()
错误信息
line 43, in <module> server_socket.bind((SERVER_IP, SERVER_PORT)) OSError: [WinError 10049] The requested address is not valid in its context
问题分析
核心错误:TCP角色完全混淆
STM32代码已经实现为TCP Server(调用netconn_listen监听端口146,等待客户端连接),但你的Python代码却也实现了TCP Server的逻辑(bind+listen+accept),两者都在等待对方发起连接,自然无法建立会话。而Hercules是作为TCP Client主动连接STM32 Server,所以能正常工作。WinError 10049错误原因
绑定STM32的IP169.254.211.100时出错,是因为这个IP不属于你的Windows主机网卡,bind操作只能绑定本机已存在的IP地址或者0.0.0.0(代表监听本机所有网卡),绑定其他设备的IP地址必然会触发地址无效的错误。绑定0.0.0.0无法连接的原因
此时Python处于Server模式,和STM32的Server模式形成“双等”状态,没有任何一方主动发起连接请求,因此永远无法建立连接。
解决方法
将Python代码修改为TCP Client逻辑,主动连接STM32 Server:
import socket # STM32服务器的IP和端口 STM32_SERVER_IP = "169.254.211.100" STM32_SERVER_PORT = 146 # 创建TCP客户端socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # 主动连接STM32服务器 client_socket.connect((STM32_SERVER_IP, STM32_SERVER_PORT)) print("已成功连接到STM32服务器") # 根据STM32代码逻辑,需要先发送数据才会触发回复 # 发送字符'g'(ASCII码103),对应STM32中msg[0]==103的判断 client_socket.send(b'g') # 接收STM32返回的数据 data = client_socket.recv(1024) if data: print("收到STM32数据:", data.decode()) finally: # 关闭连接 client_socket.close()
补充说明
- 确保Windows主机与STM32处于同一网络环境,且能正常ping通
169.254.211.100 - 如果需要持续接收STM32的数据,可以将接收逻辑放入循环中
- STM32代码逻辑是收到客户端数据后才会回复,因此Python客户端必须先发送数据才能触发STM32的返回
内容的提问来源于stack exchange,提问作者AK16
相关产品推荐
相关产品推荐

