VS下网络快速连接检测实现

一.问题:

VS实现PC软件和单片机的网络连接的时候,如果网线没有插入,检测连接失败,一般设置网络连接为非阻塞方式,但是如果单片机返回比较慢,会导致正常情况下也连不上,下面代码通过

设置等待方法解决此问题

二.代码如下:

1.连接代码

WSADATA wsaData;

g_Socket = INVALID_SOCKET;

struct addrinfo* result = NULL, * ptr = NULL, hints;

int iResult;

// 初始化 Winsock

iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

if (iResult != 0) {

printf("WSAStartup failed: %d\n", iResult);

return -1;

}

ZeroMemory(&hints, sizeof(hints));

hints.ai_family = AF_INET;

hints.ai_socktype = SOCK_STREAM;

hints.ai_protocol = IPPROTO_TCP;

// 解析服务器地址和端口

iResult = getaddrinfo(ServerIP, DEFAULT_PORT, &hints, &result);

if (iResult != 0) {

printf("getaddrinfo failed: %d\n", iResult);

WSACleanup();

return -1;

}

ptr = result;

// 创建套接字

g_Socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);

if (g_Socket == INVALID_SOCKET) {

printf("socket failed: %ld\n", WSAGetLastError());

WSACleanup();

return -1;

}

socket_nonblock(g_Socket);

// 连接到服务器

iResult = connect(g_Socket, ptr->ai_addr, (int)ptr->ai_addrlen);

if (iResult == SOCKET_ERROR) { //非阻塞模式可能太快没有连接成功,这里再进行延时检测

int error = WSAGetLastError();

if (error == WSAEWOULDBLOCK) {

// 连接操作正在进行中

fd_set writefds;

FD_ZERO(&writefds);

FD_SET(g_Socket, &writefds);

struct timeval timeout = { 1, 0 }; // 1秒超时

int result = select(0, NULL, &writefds, NULL, &timeout);

if (result > 0 && FD_ISSET(g_Socket, &writefds))

{

int err;

socklen_t errlen = sizeof(err);

getsockopt(g_Socket, SOL_SOCKET, SO_ERROR, (char*)&err, &errlen);

if (err == 0) {

// 连接成功

printf("Connected successfully.\n");

}

else {

// 连接失败,处理错误

printf("Connect failed with error: %d\n", err);

closesocket(g_Socket);

g_Socket = INVALID_SOCKET;

return -1;

}

}

else

{

// 超时或其他错误

printf("Connect timed out or error occurred.\n");

closesocket(g_Socket);

g_Socket = INVALID_SOCKET;

return -1;

}

}

else

{

// 其他连接错误

printf("Connect failed with error 2: %d\n", error);

closesocket(g_Socket);

g_Socket = INVALID_SOCKET;

return -1;

}

}

else

{

// 连接成功

printf("Connected immediately.\n");

}

freeaddrinfo(result);

2.子函数

int socket_nonblock(SOCKET sock) {

int mode;

mode = 1;

return ioctlsocket(sock, FIONBIO, &mode);

}

相关推荐
三体世界3 分钟前
TCP传输控制层协议深入理解
linux·服务器·开发语言·网络·c++·网络协议·tcp/ip
泷羽Sec-静安21 分钟前
OSCP官方靶场-Solstice WP
服务器·网络·数据库
随心点儿25 分钟前
使用python 将多个docx文件合并为一个word
开发语言·python·多个word合并为一个
不学无术の码农28 分钟前
《Effective Python》第十三章 测试与调试——使用 Mock 测试具有复杂依赖的代码
开发语言·python
华不完33 分钟前
下一代防火墙混合模式部署
运维·服务器·网络
tomcsdn3134 分钟前
SMTPman,smtp的端口号是多少全面解析配置
服务器·开发语言·php·smtp·邮件营销·域名邮箱·邮件服务器
EnigmaCoder39 分钟前
Java多线程:核心技术与实战指南
java·开发语言
longze_71 小时前
frp内网穿透下创建FTP(解决FTP“服务器回应不可路由的地址。使用服务器地址替代”错误)
运维·服务器·网络
cui_win2 小时前
【网络】Linux 内核优化实战 - net.ipv4.tcp_keepalive_time
linux·网络·tcp/ip
令狐掌门2 小时前
tcp长连接与短连接
网络·网络协议·tcp/ip