面试题答案
一键面试常见连接错误
- 连接超时:由于网络延迟、服务器负载高等原因,客户端在规定时间内未能与服务器建立连接。
- 连接被拒绝:通常是因为服务器未在指定端口监听,或者防火墙阻止了连接。
- 地址错误:包括IP地址错误、端口号错误等,导致无法定位到目标服务器。
错误捕获与处理
连接超时
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#define PORT 8080
#define IP "127.0.0.1"
#define TIMEOUT_SECONDS 3
int main(int argc, char const *argv[]) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
struct timeval timeout;
timeout.tv_sec = TIMEOUT_SECONDS;
timeout.tv_usec = 0;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = inet_addr(IP);
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) < 0) {
perror("setsockopt failed");
close(sock);
exit(EXIT_FAILURE);
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
if (errno == EINPROGRESS) {
printf("Connection timed out\n");
} else {
perror("connect failed");
}
close(sock);
exit(EXIT_FAILURE);
}
// 连接成功后的操作
close(sock);
return 0;
}
在上述代码中,通过 setsockopt
设置了连接的发送超时时间,在 connect
失败后,通过检查 errno
是否为 EINPROGRESS
判断是否连接超时。
连接被拒绝
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#define PORT 8080
#define IP "127.0.0.1"
int main(int argc, char const *argv[]) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = inet_addr(IP);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
if (errno == ECONNREFUSED) {
printf("Connection refused\n");
} else {
perror("connect failed");
}
close(sock);
exit(EXIT_FAILURE);
}
// 连接成功后的操作
close(sock);
return 0;
}
这里在 connect
失败后,通过检查 errno
是否为 ECONNREFUSED
判断是否连接被拒绝。
地址错误
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#define PORT 8080
#define IP "127.0.0.256" // 错误的IP地址
int main(int argc, char const *argv[]) {
int sock = 0, valread;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, IP, &serv_addr.sin_addr) <= 0) {
printf("Invalid address/ Address not supported \n");
close(sock);
exit(EXIT_FAILURE);
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect failed");
close(sock);
exit(EXIT_FAILURE);
}
// 连接成功后的操作
close(sock);
return 0;
}
在设置服务器地址时,通过 inet_pton
函数检查IP地址的有效性,如果返回值小于等于0,则说明地址无效。在 connect
失败后,通过 perror
输出错误信息,可从中发现地址相关错误。