You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 03:24:52