4

私は自分のニーズに合わせて単純な TCP ソケットを模倣するために、いくつかの winsock 関数をカプセル化したクラスを作成しました...

簡単な接続とデータのサーバーへの送信テストを実行しようとすると、 MSDN の接続機能のエラー コード 10049 (WSAEADDRNOTAVAIL) で接続の呼び出しに「クライアント」が失敗します。

私がやっていることは(以下のコード)です: サーバー:

  1. サーバーソケットを作成します->ポート12345にバインドします
  2. ソケットをリッスン モードにする
  3. 通話受付

クライアント

  1. ソケットを作成 -> ランダムなポートにバインド
  2. Call Connect: 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 をカプセル化する関数オブジェクトです... -デバッガーを使用してステップスルーするとき、またはそれらを単独で実行するときに、エラーを返すサーバー関数はなく、期待どおりに動作します...

問題が何であるかについての提案を聞いてうれしいです...

編集:に接続していないときに機能します、... アドレス解決プロセスを調べると、127.0.0.1の実際の IPが得られます("localhost","12345")("",12345)getaddrinfo"localhost"""

ループバック IP で機能しないのはなぜですか?

4

2 に答える 2

5

あなたの質問に答えがあります:

...それは私の本当のIPを127.0.0.1与えます"localhost"""

これは、サーバーが ではなくインターフェイスの実際の IP にバインドすることを意味しますINADDR_ANY。つまり、ループバックをリッスンしません。

編集 0:

リッスン ソケットを作成するときは、名前解決は必要ありません。利用可能なすべてのインターフェイス (ループバックを含む) をリッスンするbind()だけです。INADDR_ANY

于 2012-08-15T15:13:00.837 に答える