winsock: eine Verbindung schlägt fehl mit Fehler 10049 bei der Verwendung von localhost (127.0.0.1)
schrieb ich eine Klasse gekapselt einige winsock-Funktionen zu imitieren, eine einfache TCP-socket-für meine Bedürfnisse...
Wenn ich versuche, führen Sie eine einfache connect-and-send-Daten-zu-server-test der "client" nicht auf Ihren Anruf zu verbinden mit dem Fehlercode 10049 (WSAEADDRNOTAVAIL) connect-Funktion auf MSDN
Was ich Tue, ist (code weiter unten):
Server:
- Erstellen Sie eine Server-Socket -> Binden Sie es an Port 12345
- Setzen der Socket im listen-mode
- Anruf annehmen
Client
- Ein socket erstellen -> Binden Sie es an einen zufälligen port
- Aufruf von Connect: Verbindung zu localhost, port 12345
=> der Aufruf von connect schlägt fehl mit Fehler 10049, wie oben beschrieben
Hier ist die wichtigste Funktion, einschließlich der "server":
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)
{...
Client-thread-Funktion
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;
}...
Die Connect-Funktion
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;
}
Zusätzliche Informationen:
-Incgetaddrinfo ist ein function-Objekt encapuslating getaddrinfo...
-Niemand von den server-Funktionen Rückgabe einer Fehlermeldung und funktioniert wie erwartet, wenn Sie Durchlaufen mit dem debugger oder, wenn man Sie führen allein...
Ich würde gerne Ihre Vorschläge hören, was das rpoblem sein könnte...
Edit: Es funktioniert, wenn ich dont verbinden ("localhost","12345")
, aber zu ("",12345)
...
Beim Blick in das address-resolution-Prozess der getaddrinfo
es gibt 127.0.0.1 für "localhost"
und meine echte IP - für ""
Warum geht es nicht mit meinem loopback-IP?
InformationsquelleAutor Incubbus | 2012-08-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie die Antwort in deiner Frage:
Bedeutet dies, dass Ihr server bindet Sie an die Reale IP des interface statt
INADDR_ANY
ist, d.h. er hört nicht auf die loopback.Edit 0:
Sie nicht wirklich brauchen, die Namensauflösung beim erstellen von socket. Nur
bind()
es zuINADDR_ANY
zu hören, die auf allen verfügbaren Schnittstellen (einschließlich der loopback).netstat -na
wird zeigen, was von ports gehört wird, auf welchen Adressen. IIRC-b
- option auf Windows wird Ihnen zeigen, welche Programme zu verwenden, welche verbindungen.ok... wenn ich binden "" (INADDR_ANY wegen gesetztem ai_passive-bit in den hinweisen von getaddrinfo) es bindet an die 192..... und hört auf, die ip mit port 12345 (netstat -na) =>trying to connect via "arbeitet", aber localhost schlägt fehl... die Bindung des server-socket auf localhost macht es listen auf 127.0.0.1 (netstat) => Verbindung über "" schlägt fehl, und über localhost schlägt fehl, auch...
Dude, hast du oder hast du nicht "bind()" zu "INADDR_ANY"? Wenn nicht, warum nicht???
"Dude", ja, habe ich - wie oben beschrieben - durch die übergabe einer leeren Zeichenfolge getaddrinfo und mit der fahne gesetztem ai_passive-bit (msdn.microsoft.com/en-us/library/ms738520(v=vs. 85) => nach unten, um die Flag-Bits Tabelle)
InformationsquelleAutor Nikolai Fetissov