嵌入式系统TCP客户端连接服务器时卡住的问题求助
跨设备TCP连接失败:客户端卡在连接阶段
我是Socket编程新手,此前参考教程实现了本地TCP通信,现在希望实现电脑(作为服务器)与嵌入式系统(作为客户端)的跨设备TCP连接。我修改了客户端代码中servaddr.sin_addr.s_addr字段,填入了服务器的IP地址,但客户端卡在连接阶段。
服务器代码(电脑端gcc编译)
#include <stdio.h> #include <netdb.h> #include <netinet/in.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> // read(), write(), close() #define MAX 80 #define PORT 8080 #define SA struct sockaddr // Function designed for chat between client and server. void func(int connfd) { char buff[MAX]; int n; // infinite loop for chat for (;;) { bzero(buff, MAX); // read the message from client and copy it in buffer read(connfd, buff, sizeof(buff)); // print buffer which contains the client contents printf("From client: %s\t To client : ", buff); bzero(buff, MAX); n = 0; // copy server message in the buffer while ((buff[n++] = getchar()) != '\n') ; // and send that buffer to client write(connfd, buff, sizeof(buff)); // if msg contains "Exit" then server exit and chat ended. if (strncmp("exit", buff, 4) == 0) { printf("Server Exit...\n"); break; } } } // Driver function int main() { int sockfd, connfd, len; struct sockaddr_in servaddr, cli; // socket create and verification sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } else printf("Socket successfully created..\n"); bzero(&servaddr, sizeof(servaddr)); // assign IP, PORT servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); // Binding newly created socket to given IP and verification if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { printf("socket bind failed...\n"); exit(0); } else printf("Socket successfully binded..\n"); // Now server is ready to listen and verification if ((listen(sockfd, 5)) != 0) { printf("Listen failed...\n"); exit(0); } else printf("Server listening..\n"); len = sizeof(cli); // Accept the data packet from client and verification connfd = accept(sockfd, (SA*)&cli, &len); if (connfd < 0) { printf("server accept failed...\n"); exit(0); } else printf("server accept the client...\n"); // Function for chatting between client and server func(connfd); // After chatting close the socket close(sockfd); }
客户端代码(嵌入式系统gcc编译)
#include <arpa/inet.h> // inet_addr() #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> // bzero() #include <sys/socket.h> #include <unistd.h> // read(), write(), close() #define MAX 80 #define PORT 8080 #define SA struct sockaddr void func(int sockfd) { char buff[MAX]; int n; for (;;) { bzero(buff, sizeof(buff)); printf("Enter the string : "); n = 0; while ((buff[n++] = getchar()) != '\n') ; write(sockfd, buff, sizeof(buff)); bzero(buff, sizeof(buff)); read(sockfd, buff, sizeof(buff)); printf("From Server : %s", buff); if ((strncmp(buff, "exit", 4)) == 0) { printf("Client Exit...\n"); break; } } } int main() { int sockfd, connfd; struct sockaddr_in servaddr, cli; // socket create and verification sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printf("socket creation failed...\n"); exit(0); } else printf("Socket successfully created..\n"); bzero(&servaddr, sizeof(servaddr)); // assign IP, PORT servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr("192.168.182.128"); servaddr.sin_port = htons(PORT); // connect the client socket to server socket if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) { printf("connection with the server failed...\n"); exit(0); } else printf("connected to the server..\n"); // function for chat func(sockfd); // close the socket close(sockfd); }
问题现象
先在电脑上运行服务器程序后,在嵌入式系统上运行客户端程序时,客户端卡在连接阶段:
root@imx8mq-var-dart:~# ./client Socket successfully created.. (在此处无限卡住)
排查与解决步骤
1. 确认基础网络连通性
- 在嵌入式设备上执行
ping 192.168.182.128,如果丢包或完全不通,先解决网络链路问题:- 检查两者是否在同一IP网段,子网掩码是否一致
- 确认网线连接正常,交换机/路由器工作正常
- 若跨网段,检查嵌入式设备的网关设置是否正确,能否正常访问网关
- 同时在服务器上ping嵌入式设备的IP,确保双向连通
2. 验证服务器端口是否正常监听
在服务器终端执行:
netstat -tulpn | grep 8080
确认输出中存在0.0.0.0:8080或:::8080(对应INADDR_ANY),且进程是你的服务器程序。如果没有监听,检查服务器程序是否正常启动、有无报错。
3. 检查端口可达性
在嵌入式设备上执行以下命令测试8080端口是否能连通:
telnet 192.168.182.128 8080
或用nc工具:
nc -zv 192.168.182.128 8080
如果连接失败,大概率是服务器端的防火墙/安全组拦截了端口。
4. 关闭或配置服务器防火墙
- Ubuntu/Debian系统:
临时关闭防火墙测试:
或永久添加端口允许规则:sudo ufw disablesudo ufw allow 8080/tcp - CentOS/RHEL系统:
临时关闭防火墙测试:
或永久添加端口规则:sudo systemctl stop firewalldsudo firewall-cmd --add-port=8080/tcp --permanent sudo firewall-cmd --reload - 部分杀毒软件也会拦截端口,可暂时关闭测试。
5. 代码层面的优化与检查
- 客户端的
inet_addr函数如果传入无效IP会返回INADDR_NONE,建议添加错误检查:in_addr_t server_ip = inet_addr("192.168.182.128"); if (server_ip == INADDR_NONE) { printf("Invalid server IP address\n"); exit(1); } servaddr.sin_addr.s_addr = server_ip; - 服务器代码中
accept是阻塞调用,但只要服务器正常监听,问题根源还是在网络层面,优先排查前面的网络问题。
内容的提问来源于stack exchange,提问作者zianuro_
相关产品推荐
相关产品推荐

