INET is not recommended when writing WinSock code_ The reason for addr function

When writing WinSock code, I believe that you will generally use inet_addr function to convert a dotted decimal string to sin_addr.S_un.S_addr, as follows

	SOCKADDR_IN sockaddr;
	sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

However, due to INET_ The addr function has no error judgment mechanism, so when an incorrect dotted decimal string is passed in, INET_ The addr function will still execute successfully, and then there will be a crying and laughing phenomenon, as shown below

	SOCKADDR_IN sockaddr;
    sockaddr.sin_addr.S_un.S_addr = inet_addr("127");
    auto pAddr = inet_ntoa(sockaddr.sin_addr);
    if (pAddr != NULL)
    {
    	std::cout << pAddr << "\n";
    }
    
    sockaddr.sin_addr.S_un.S_addr = inet_addr("127.1");
	pAddr = inet_ntoa(sockaddr.sin_addr);
    if (pAddr != NULL)
    {
    	std::cout << pAddr << "\n";
    }

The above code runs on VS2017 as follows

The output does not match the parameters passed in at all.

So when writing WinSock code, INET is not recommended_ Addr function, INET should be used_ The Pton function converts the dotted decimal string as follows

	SOCKADDR_IN sockaddr;
	char szAddress[255] = { 0, };
    int nRetValue = inet_pton(AF_INET, "127", &sockaddr.sin_addr);
    if (nRetValue != 0)
    {
        auto pAddress = inet_ntop(AF_INET, &sockaddr.sin_addr, szAddress, sizeof(szAddress));
        if (pAddress != NULL)
        {
            std::cout << pAddress << '\n';
        }
    }
    
    nRetValue = inet_pton(AF_INET, "127.1", &sockaddr.sin_addr);
    if (nRetValue != 0)
    {
        auto pAddress = inet_ntop(AF_INET, &sockaddr.sin_addr, szAddress, sizeof(szAddress));
        if (pAddress != NULL)
        {
            std::cout << pAddress << '\n';
        }
    }

    nRetValue = inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr);
    if (nRetValue != 0)
    {
        auto pAddress = inet_ntop(AF_INET, &sockaddr.sin_addr, szAddress, sizeof(szAddress));
        if (pAddress != NULL)
        {
            std::cout << pAddress << '\n';
        }
    }

The results of the above code running on VS2017 are as follows

It can be seen that when the input dotted decimal format is wrong, INET_ The Pton function returns a non-zero value, otherwise it returns a 0 value. More about INET_ The introduction of Pton function can be found on this website: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-inet_pton.

As for INET_ The introduction website of addr function is: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-inet_addr ´╝îinet_ The introduction website of the ntoa function is: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-inet_ntoa ´╝îinet_ The introduction website of the ntop function is: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-inet_ntop.

In my opinion, inet_ntoa function and INET_ There is no difference in the general use of ntop function, but INET_ ipv6 is not supported for the ntoa function. INET on conversion failure_ Ntoa function and INET_ The ntop functions all return NULL.

But, inet_pton function and INET_ The ntop function is only supported by Windows Vista and later versions. What about running programs on Windows XP? (PS: don't tell me that Windows XP has not been used for a long time, t_ There are many antique machines using Windows XP in places you can't imagine.)

Because Windows does not provide inet_aton function, so we have to use INET inevitably_ Addr function. Then we can execute INET_ Before the addr function is converted, the regular expression is used to determine whether the string is the correct ipv4 address. The code is as follows

	std::regex regexIpAddress("(?=(\\b|\\D))(((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{1,2})|(2[0-4]\\d)|(25[0-5]))(?=(\\b|\\D))");
    if (!std::regex_match("127", regexIpAddress))
    {
        std::cout << "not match\n";
    }
    else
    {
        std::cout << "match\n";
    }

    if (!std::regex_match("127.1", regexIpAddress))
    {
        std::cout << "not match\n";
    }
    else
    {
        std::cout << "match\n";
    }

    if (!std::regex_match("127.0.0.1", regexIpAddress))
    {
        std::cout << "match\n";
    }
    else
    {
        std::cout << "match\n";
    }

The execution results of the above code on VS2017 are as follows

The above is the full text of this blog. I am limited to my ability. There are inevitably mistakes in the above. If the readers find the mistakes in the above, please point out in the comment area. I will modify them as soon as I see them. Thank you.

Tags: Windows

Posted on Fri, 19 Jun 2020 04:48:49 -0400 by ofaltins