当没有互联网连接

时间:2016-07-31 06:54:47

标签: c++ sockets winsock winsock2

当我没有互联网连接时,为什么socket()不会返回INVALID_SOCKET?我以为它会失败然后我可以退出我的功能。我的函数的错误检查一直持续到recvfrom(),然后在我没有互联网连接时挂起。当我没有互联网连接时,我认为socket()sendto()会返回错误代码,但事实并非如此。我试图依靠他们的失败作为一个标志,用户没有互联网连接并退出我的功能,但那只是因为一些奇怪的原因不起作用。

void myFunc()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("myipaddress");
    server_addr.sin_port = htons(123);

    // Doesn't fail when there's no internet connection
    protoent *proto = getprotobyname("udp");
    int s = socket(PF_INET, SOCK_DGRAM, proto->p_proto);
    if (s == INVALID_SOCKET) {
        goto Cleanup;
    }

    // Doesn't fail when there's no internet connection
    char msg[48] = { 0x08, 0, 0, 0, 0, 0, 0, 0, 0 };
    int iResult = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &server_addr, sizeof(server_addr));
    if (iResult == SOCKET_ERROR) {
        goto Cleanup;
    }

    // Hangs when there's no internet connection
    memset(msg, 0, sizeof(msg));
    struct sockaddr saddr;
    socklen_t saddr_l = sizeof(saddr);
    iResult = recvfrom(s, msg, 48, 0, &saddr, &saddr_l);
    if (iResult == SOCKET_ERROR) {
        goto Cleanup;
    }

Cleanup:
    closesocket(s);
    WSACleanup();
}

2 个答案:

答案 0 :(得分:2)

因为不需要将套接字连接到互联网。许多应用程序使用套接字在单个机器上进行进程间通信。没有互联网连接时,此类应用程序仍可正常运行。

sendto()可能会返回错误代码;它可以(在某些情况下,如关于网络连接状态的桌面通知所示)知道数据包永远不会被传递。但是,UDP通信和sendto()不保证任何交付,显然您正在使用的实现不考虑缺少值得错误代码的连接。可以说这是一个实施质量问题。

recvfrom()只要您指定(可能无限期)一条消息,但只是等待,但永远不会收到消息。同样,这是在规范内,并且无论该特定情况是否被标记,它都可以被认为是实施质量问题。

答案 1 :(得分:0)

我查看了sendto的linux手册页(假设所有相关的实现与berkley套接字基线完全相似):

http://linux.die.net/man/2/sendto

如果网络堆栈知道'文档没有提及报告和错误。消息无法传递。这是合理的,因为套接字的传输可能不是IP4或IP6。它可能是我们选择编写驱动程序的任何传输方式:分组无线电,串行电缆或载波(如果我们能够找出用于将打印的消息加载到其书包中的硬件)。

传输中可能出现的错误的唯一参考是:

  

这些是套接字层生成的一些标准错误。可以生成附加错误并从底层协议模块返回; 查看各自的手册页

正如其他人所说,UDP是一种不可靠的数据报协议。预计不可靠。预计不会传递消息。因此不是一个真正的错误。对于协议层作者来说,处理传输错误的代码几乎没有什么动力 - 因为它们也是预期的,而不是该协议上下文中的错误。

通过TCP打开套接字时,缺少套接字连续性是一个错误。如果传输报告无法传送数据包(足够长的时间),那么这是协议中的错误条件。