winsock: ошибка подключения с ошибкой 10049 при использовании localhost (127.0.0.1)

Я написал класс, инкапсулирующий некоторые функции winsock, чтобы имитировать простой сокет TCP для моих нужд...

Когда я пытаюсь запустить простой тест подключения и отправки данных на сервер, "клиент" не может подключиться к нему с кодом ошибки 10049 (WSAEADDRNOTAVAIL), функция подключения на MSDN

Что я делаю, это (код ниже): Сервер:

  1. Создайте сокет сервера -> привяжите его к порту 12345
  2. Переведите сокет в режим прослушивания
  3. Звонок принять

клиент

  1. Создать сокет -> привязать его к случайному порту
  2. Call Connect: подключение к локальному хосту, порт 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 это дает 127.0.0.1 для "localhost" и мой реальный IP для ""

Почему это не работает с моим loopback-IP?

2 ответа

Решение

У вас есть ответ на ваш вопрос:

... это дает 127.0.0.1 за "localhost" и мой реальный IP для ""

Это означает, что ваш сервер привязывается к реальному IP интерфейса вместо INADDR_ANYто есть он не слушает петлю.

Изменить 0:

При создании сокета для прослушивания вам не нужно разрешение имен. Просто bind() это к INADDR_ANY прослушивать все доступные интерфейсы (включая петлю).

В моем случае эта ошибка была вызвана тем, что не позвонил htonl на INADDR_LOOPBACK прежде чем назначить его address.sin_addr.s_addr.

Убедитесь, что вы конвертируете в сетевой порядок байтов, иначе вы получите 0x0100007f (1.0.0.127) вместо того 0x7f000001 (127.0.0.1) для вашего адреса обратной связи, и привязка не удастся с кодом 10049 (WSAEADDRNOTAVAIL).

Другие вопросы по тегам