winsock:使用localhost(127.0.0.1)时连接失败,错误10049

时间:2012-08-15 13:22:58

标签: c++ windows sockets winsock connect

我写了一个封装了一些winsock函数的类来模仿我需要的简单TCP套接字...

当我尝试运行简单的连接和发送数据到服务器测试时,“客户端”在其调用失败时连接错误代码10049(WSAEADDRNOTAVAIL)connect function on MSDN

我在做什么(下面的代码): 服务器

  1. 创建服务器套接字 - >将其绑定到端口12345
  2. 将Socket置于侦听模式
  3. 致电接受
  4. 客户端

    1. 创建套接字 - >将它绑定到随机端口
    2. 呼叫连接:连接到 localhost,端口12345
    3. =>对连接的调用失败,错误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一起使用?

1 个答案:

答案 0 :(得分:4)

你的问题有答案:

...它为127.0.0.1提供了"localhost",为""提供了我的真实IP

这意味着您的服务器绑定到接口的真实IP而不是INADDR_ANY,即它不会侦听环回。

编辑0:

创建侦听套接字时,您真的不需要名称解析。只需bind()它就可以INADDR_ANY监听所有可用的接口(包括环回)。