在C++中,可以使用非阻塞的方式来进行socket连接,并设置超时时间来判断连接是否超时。下面是一个简单的示例代码:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
int connectNonBlocking(const char* ip, int port, int timeout) {
// 创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
return -1;
}
// 设置非阻塞
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
// 构建服务器地址结构体
struct sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
if (inet_pton(AF_INET, ip, &(serverAddr.sin_addr)) <= 0) {
perror("inet_pton");
close(sockfd);
return -1;
}
// 非阻塞connect,立即返回
if (connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
if (errno != EINPROGRESS) { // 连接错误,返回失败
perror("connect");
close(sockfd);
return -1;
}
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(sockfd, &writeSet);
struct timeval tv;
tv.tv_sec = timeout; // 超时时间设置为timeout秒
tv.tv_usec = 0;
// 使用select等待连接成功或超时
int ret = select(sockfd + 1, NULL, &writeSet, NULL, &tv);
if (ret == -1) { // 出错
perror("select");
close(sockfd);
return -1;
} else if (ret == 0) { // 超时
std::cout << "Connect timeout" << std::endl;
close(sockfd);
return -1;
}
// 连接成功或失败,检查错误码
int error = 0;
socklen_t len = sizeof(error);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
if (error != 0) {
std::cout << "Connect failed: " << strerror(error) << std::endl;
close(sockfd);
return -1;
}
}
// 非阻塞连接成功
std::cout << "Connect succeeded" << std::endl;
// 恢复为阻塞模式(可选)
fcntl(sockfd, F_SETFL, flags);
// 在这里可以继续进行后续的操作
return sockfd;
}
int main() {
const char* ip = "127.0.0.1";
int port = 8080;
int timeout = 5; // 超时时间设置为5秒
int sockfd = connectNonBlocking(ip, port, timeout);
if (sockfd != -1) {
// 连接成功,可以进行后续的操作
close(sockfd);
}
return 0;
}
在上述代码中,connectNonBlocking
函数实现了非阻塞连接,并设置了超时时间。首先,将socket设置为非阻塞模式,然后进行connect
操作。如果连接返回的错误码是EINPROGRESS
,表示连接正在进行中,则使用select
函数等待连接成功或超时。
当select
返回0时,表示连接超时;当select
返回大于0时,需要进一步检查错误码来确定连接是否成功。如果连接失败,则可以根据具体的错误码进行相应的处理。
注意,在上述代码中仅展示了基本的非阻塞连接和超时判断逻辑,并未对异常情况进行完全处理,请根据实际需求进行适当调整和优化。
内容由零声教学AI助手提供,问题来源于学员提问