windows winsock:当使用localhost(127.0.0.1)时,连接失败并出现错误10049

f2uvfpb9  于 2023-08-07  发布在  Windows
关注(0)|答案(2)|浏览(248)

我写了一个类封装了一些winsock函数来模仿一个简单的TCP套接字以满足我的需要。
当我尝试运行一个简单的connect-and-send-data-to-server测试时,“client”在调用连接时失败,错误代码为10049(WSAEADDRNOTAVAIL)connect function on MSDN
我正在做的是(下面的代码):服务器:
1.创建服务器套接字->将其绑定到 * 端口12345*
1.将Socket置于监听模式
1.呼叫接受

客户

1.创建一个套接字->将其绑定到随机端口
1.呼叫连接:连接到 localhost,端口12345
=>连接调用失败,出现错误10049,如上所述

这里是包含服务器的主要功能:

HANDLE hThread = NULL;
Inc::CSocketTCP ServerSock;
Inc::CSocketTCP ClientSock;

try
{

    ServerSock.Bind(L"", L"12345");
    ServerSock.Listen(10);

    //Spawn the senders-thread
    hThread = (HANDLE)_beginthreadex(nullptr, 0, Procy, nullptr, 0, nullptr);

    //accept
    ServerSock.Accept(ClientSock);

    //Adjust the maximum packet size
    ClientSock.SetPacketSize(100);

    //receive data
    std::wstring Data;
    ClientSock.Receive(Data);

    std::wcout << "Received:\t" << Data << std::endl;
}
catch(std::exception& e)
{...

字符串

客户端线程函数

unsigned int WINAPI Procy(void* p)


{

Sleep(1500);
try{
    Inc::CSocketTCP SenderSock;
    SenderSock.Bind(L"", L"123456");

    SenderSock.Connect(L"localhost", L"12345");

    //Adjust packet size
    SenderSock.SetPacketSize(100);

    //Send Data
    std::wstring Data = L"Hello Bello!";
    SenderSock.Send(Data);
}
catch(std::exception& e)
{
    std::wcout << e.what() << std::endl;
}...

连接函数

int Inc::CSocketTCP::Connect(const std::wstring& IP, const std::wstring& Port)
{
    //NOTE: assert that the socket is valid
    assert(m_Socket != INVALID_SOCKET);

    //for debuggin: convert WStringToString here
    std::string strIP = WStringToString(IP), strPort = WStringToString(Port);

    Incgetaddrinfo AddyResolver;
    addrinfo hints = {}, *pFinal = nullptr;
    
    hints.ai_family = AF_INET;

    //resolve the ip/port-combination for the connection process
    INT Ret = AddyResolver(strIP.c_str(), strPort.c_str(), &hints, &pFinal);
    if(Ret)
    {
        //error handling: throw an error description
        std::string ErrorString("Resolving Process failed (Connect): ");
        ErrorString.append(Inc::NumberToString<INT>(Ret));
        throw(std::runtime_error(ErrorString.c_str()));
    }

    /*---for debbuging---*/
    sockaddr_in *pP = (sockaddr_in*)(pFinal->ai_addr);
    u_short Porty = ntohs(pP->sin_port);
    char AddBuffer[20] = "";

    InetNtopA(AF_INET, (PVOID)&pP->sin_addr, AddBuffer, 20);
    /*--------------------------------------------------------*/

    if(connect(m_Socket, pFinal->ai_addr, pFinal->ai_addrlen) == SOCKET_ERROR)
    {
        int ErrorCode = WSAGetLastError();
        if((ErrorCode == WSAETIMEDOUT) || (ErrorCode == WSAEHOSTUNREACH) || (ErrorCode == WSAENETUNREACH))
        {
            //Just Unreachable
            return TCP_TARGETUNREACHABLE;
        }

        //real errors now
        std::string ErrorString("Connection Process failed: ");
        ErrorString.append(Inc::NumberToString<int>(ErrorCode));
        throw(std::runtime_error(ErrorString.c_str()));
    }

    return TCP_SUCCESS;
}

附加说明:-Incgetaddrinfo是封装getaddrinfo的函数对象... - 没有一个服务器函数返回任何错误,并按预期工作时,使用调试器单步执行它们或当让它们单独运行。

我很乐意听听你的建议问题可能是什么。。
当我连接到("localhost","12345")连接到("",12345)...在查看getaddrinfo的地址解析过程时,"localhost"的地址解析结果为127.0.0.1""真实的IP
为什么我的loopback-IP不工作?

hgc7kmma

hgc7kmma1#

你的问题中有答案:
.它给127.0.0.1"localhost"和我的真实的IP为""
这意味着您的服务器绑定到接口的真实的IP,而不是INADDR_ANY,即它不会监听环回。

编辑0:

在创建侦听套接字时,实际上并不需要名称解析。只需bind()INADDR_ANY来侦听所有可用的接口(包括环回)。

au9on6nz

au9on6nz2#

在我的例子中,这个错误是由于在将INADDR_LOOPBACK分配给address.sin_addr.s_addr之前没有在INADDR_LOOPBACK上调用htonl而导致的。
请确保转换为网络字节顺序,否则您将获得0x0100007f (1.0.0.127)而不是0x7f000001 (127.0.0.1)作为环回地址,并且绑定将失败,代码为10049 (WSAEADDRNOTAVAIL)

相关问题