winsock: ошибка подключения с ошибкой 10049 при использовании localhost (127.0.0.1)
Я написал класс, инкапсулирующий некоторые функции winsock, чтобы имитировать простой сокет TCP для моих нужд...
Когда я пытаюсь запустить простой тест подключения и отправки данных на сервер, "клиент" не может подключиться к нему с кодом ошибки 10049 (WSAEADDRNOTAVAIL), функция подключения на MSDN
Что я делаю, это (код ниже): Сервер:
- Создайте сокет сервера -> привяжите его к порту 12345
- Переведите сокет в режим прослушивания
- Звонок принять
клиент
- Создать сокет -> привязать его к случайному порту
- 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)
.