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 天前
【网络安全就业】信息安全专业的就业前景(非常详细)零基础入门到精通,收藏这篇就够了
网络·安全·web安全·计算机·程序员·编程·网络安全就业
侃侃_天下3 天前
最终的信号类
开发语言·c++·算法
echoarts3 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
树码小子3 天前
Java网络编程:(socket API编程:TCP协议的 socket API -- 回显程序的服务器端程序的编写)
java·网络·tcp/ip
Aomnitrix3 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题3 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说3 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔3 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
绿箭柠檬茶3 天前
Ubuntu 服务器配置转发网络访问
服务器·网络·ubuntu
我是菜鸟0713号3 天前
Qt 中 OPC UA 通讯实战
开发语言·qt