Winsock接受不回来

时间:2018-02-22 10:12:37

标签: c++ sockets winsock2

我在套接字上做了一个简单的c ++包装,我在windows上遇到了问题。我初始化我的服务器套接字没有任何错误但是当我尝试使用netcat localhost 4242连接时,不接受连接(接受永远不会在服务器套接字上返回)。

这是我使用

的代码
skt::tcp::Socket serv_socket(port_);

while (!stop_flag_)
{
    skt::tcp::Socket cli_socket;
    std::cout << "Accepting clients..." << std::endl;
    serv_socket.accept(cli_socket);
    std::cout << "New client connected : " << std::endl;
    //blabla handle the connection
}

BaseSocket.cpp

    BaseSocket::BaseSocket(int domain, int type, int protocol, const std::string &port)
{
    struct addrinfo hints;

#ifdef _WIN32
  WSADATA wsa{};

  if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
  {
    throw SocketException(std::string("Unable to initialize the socket: ") +
                          printLastError());
  }
#endif

  memset(&hints, 0, sizeof hints); // make sure the struct is empty
  hints.ai_family = domain;     // don't care IPv4 or IPv6
  hints.ai_socktype = type; 
  hints.ai_protocol = protocol;
  hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

  if (getaddrinfo(NULL, port.c_str(), &hints, &servinfo_) != 0) {
      printf("getaddrinfo failed");
      //WSACleanup();
  }


  mFd = socket(servinfo_->ai_family, servinfo_->ai_socktype, servinfo_->ai_protocol);
  std::cout << "Error init socket " << WSAGetLastError() << " " << mFd << std::endl;

  if (mFd == INVALID_SOCKET)
    throw SocketException(std::string("Unable to initialize the socket: ") +
                          printLastError());
}


BaseSocket::BaseSocket(int domain, int type, int protocol)
{

#ifdef _WIN32
    WSADATA wsa{};

    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        throw SocketException(std::string("Unable to initialize the socket: ") +
            printLastError());
    }
#endif

}

void BaseSocket::bind()
{
  if (::bind(mFd, servinfo_->ai_addr, (int)servinfo_->ai_addrlen) == SOCKET_ERROR)
    throw SocketException(std::string("address binding failed: ") + printLastError());
}

void BaseSocket::listen(int backlog)
{
  if (::listen(mFd, backlog) ==  SOCKET_ERROR)
    throw SocketException(std::string("listen setting failed: ") + printLastError());
}

void BaseSocket::accept(BaseSocket &clientSocket, sockaddr *addr, socklen_t *addrlen)
{
    std::cout << "pre accept" << std::endl;
  clientSocket.mFd = ::accept(mFd, addr, addrlen);

  if (clientSocket.mFd == INVALID_SOCKET) {
      printLastError();
      std::cout << "Error onm accept " << WSAGetLastError() << std::endl;
      throw SocketException(std::string("accept failed: ") + printLastError());
  }
}

Socket.cpp

Socket::Socket(int port) :
        BaseSocket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "4242")
    {
        std::cout << "Init server socket" << std::endl;
        enableReuseAddr();
        bind();
    }

    Socket::Socket() :
        BaseSocket(SocketDomain::IP, SocketType::TCP, 0)
    {
        std::cout << "Init client socket" << std::endl;

    }

    void Socket::accept(Socket &clientSocket, int backlog)
    {
      sockaddr addr{};
      socklen_t addrlen;

      listen(backlog);
      BaseSocket::accept(clientSocket,nullptr, nullptr);

      //clientSocket.servinfo_ = addr;
    }

知道我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

有点晚了,但是当我在“使用 C 进行网络编程”中的 time_server 示例中遇到同样的问题时,我遇到了这个问题。这个问题给了我 netcat 的链接(尽管我使用了 ncat),这帮助我弄清楚了。使用 NULL 作为 getaddrinfo 的 pNodeName 参数不一定首先返回 localhost ip 地址。使用“localhost”或“127.0.0.1”。 (您可以在 getaddrinfo 返回的地址上使用 getnameinfo 来检查您用于创建套接字的内容。)