自学内容网 自学内容网

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);

}


原文地址:https://blog.csdn.net/xieliru/article/details/144299229

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!