Mac(M1)与Orange Pi 5跨机TCP服务端客户端通信失败求助
跨机TCP通信故障排查与解决
环境信息
- 服务端:M1芯片MacBook,IP
10.0.1.165,编译命令gcc 源文件.c -o 目标文件 - 客户端:Armbian系统Orange Pi 5,IP
10.0.1.175,编译命令同上
需求与故障现象
需要实现服务端向客户端发送消息、客户端标准输出打印消息的TCP通信功能。本地运行(将inet_addr("10.0.1.165")替换为INADDR_ANY)正常,但跨机运行时:
- Mac服务端输出
error: Undefined error: 0 - Linux客户端无任何输出
最初代码
服务端 tcp_server_01.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> int main () { char server_message[250] = "message was recived form MB \n\r"; //create socket int server_socket; server_socket = socket(AF_INET, SOCK_STREAM, 0); //define addres structure struct sockaddr_in server_addres; server_addres.sin_family = AF_INET; server_addres.sin_port = htons(5067); server_addres.sin_addr.s_addr = inet_addr("10.0.1.165"); //INADDR_ANY //bind socket to specified ip and port int n = bind(server_socket, (struct sockaddr *) &server_addres, sizeof(server_addres)); //int n = bind(server_socket, &server_addres.sin_addr) perror("error"); //Listen for connections listen(server_socket, 1); int client_socket; client_socket = accept(server_socket, NULL, NULL); //send message send(client_socket, server_message, sizeof(server_message), 0); //colose socket close(server_socket); return 0; }
客户端 tcp_client_01.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <errno.h> int main() { //coreate a socket int network_socket; network_socket = socket(AF_INET, SOCK_STREAM, 0); // specify an adress for socket struct sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(5067); server_address.sin_addr.s_addr = inet_addr("10.0.1.165"); //INADDR_ANY int connection_status = connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address)); //check for errors if (connection_status == 0) { printf("connection sucessfull\n%i", connection_status); perror("Error"); }else { perror("Error"); //printf("connection unsucesfull\n"); } //string for server_response char server_response[250]; //recive data from server recv(network_socket, &server_response, sizeof(server_response), 0); //print recived data printf("message form server: %s\n", server_response); //colose socket close(network_socket); return 0; }
编辑补充:重写代码后问题依旧
重写服务端 tcp_server.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <errno.h> int main () { char server_message[250] = "message was recived form AMB \n\r"; //coresreate socket int server_socket; if((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 0; } //define addres structure struct sockaddr_in server_addres; server_addres.sin_family = AF_INET; server_addres.sin_port = htons(5067); server_addres.sin_addr.s_addr = inet_addr("10.0.1.165"); //INDOOR_ANY //bind socket to specified ip and port if(bind(server_socket, (struct sockaddr *) &server_addres, sizeof(server_addres)) != 0) { perror("bind"); return 0; } //int n = bind(server_socket, &server_addres.sin_addr) //Listen for connections if(listen(server_socket, 1) !=0) { perror("listen"); return 0; } int client_socket; if((client_socket = accept(server_socket, NULL, NULL)) == -1) { perror("accept"); return 0; } //send message if(send(client_socket, server_message, sizeof(server_message), 0) == -1) { perror("send"); return 0; } //colose socket close(server_socket); return 0; }
重写客户端 tcp_client.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <errno.h> int main() { //coreate a socket int network_socket; if((network_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket creation"); return 0; } // specify an adress for socket struct sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(5067); server_address.sin_addr.s_addr = inet_addr("10.0.1.165"); //INADDR_ANY if(connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address)) != 0) { perror("socket connection"); return 0; } //string for server_response char server_response[250]; //recive data from server if(recv(network_socket, &server_response, sizeof(server_response), 0) == -1) { perror("reciving socket"); return 0; } //print recived data printf("message form server: %s\n", server_response); //colose socket close(network_socket); return 0; }
故障排查与解决方案
1. 网络连通性验证
- 在客户端执行
ping 10.0.1.165,确认两台机器能正常通信 - 在客户端执行
telnet 10.0.1.165 5067,检查端口是否开放。若连接失败,说明端口被防火墙拦截或服务端未正确监听
2. 服务端绑定优化
- 确认MacBook当前活跃网卡IP为
10.0.1.165,执行ifconfig查看网卡信息 - 建议服务端使用
INADDR_ANY绑定所有可用网卡,避免IP变更或网卡切换导致绑定失败:server_addres.sin_addr.s_addr = INADDR_ANY;
3. 防火墙规则配置
- Mac端:关闭防火墙或添加5067端口TCP允许规则:
sudo pfctl -e echo "pass in proto tcp from any to any port 5067" | sudo pfctl -f - - Orange Pi端:添加端口允许规则:
sudo ufw allow 5067/tcp # 或使用iptables sudo iptables -A INPUT -p tcp --dport 5067 -j ACCEPT
4. 代码逻辑修正
- 服务端:发送消息后先关闭客户端套接字,再关闭服务端套接字,避免客户端未完整接收数据:
//send message if(send(client_socket, server_message, sizeof(server_message), 0) == -1) { perror("send"); close(client_socket); close(server_socket); return 0; } //close sockets close(client_socket); close(server_socket); - 客户端:
recv返回实际接收字节数,需手动添加字符串结束符避免乱码:ssize_t recv_len = recv(network_socket, server_response, sizeof(server_response)-1, 0); if(recv_len == -1) { perror("reciving socket"); close(network_socket); return 0; } server_response[recv_len] = '\0'; // 添加字符串结束符
5. 错误处理增强
- 检查
inet_addr返回值,避免无效IP导致的绑定失败:in_addr_t server_ip = inet_addr("10.0.1.165"); if(server_ip == INADDR_NONE) { perror("invalid server IP"); return 0; } server_addres.sin_addr.s_addr = server_ip;
内容的提问来源于stack exchange,提问作者Tomas barta
相关产品推荐
相关产品推荐

