2014-04-14 290 views
2

我在同一台计算机上运行客户端和服务器。 客户端通过端口80连接到127.0.0.1。服务器同时在端口80上侦听。尝试连接winsock时出现错误10061

当我启动客户端并尝试连接时,会抛出错误10061(主动拒绝目标计算机)。我尝试关闭本地防火墙,但这并没有改变任何东西。 我绝对坚持这一点。下面是连接到服务器的代码:

void Base::Connect(string ip, string port) 
{ 
    int status; 
    SOCKET ConnectSocket = INVALID_SOCKET; 
    struct addrinfo hints; 
    struct addrinfo *servinfo; // will point to the results 

    memset(&hints, 0, sizeof hints); // make sure the struct is empty 
    hints.ai_family = AF_UNSPEC;  // don't care IPv4 or IPv6 
    hints.ai_socktype = SOCK_STREAM; // TCP stream sockets 

    // get ready to connect 
    status = getaddrinfo(ip.c_str(), port.c_str(), &hints, &servinfo); 

    // Socket Setup 
    if ((ConnectSocket = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == INVALID_SOCKET) 
    { 
     printf("[NETWORKING] An error occured when setting up socket\n"); 
    } 

    // Connect 
    WSACleanup(); 
    if (connect(ConnectSocket, servinfo->ai_addr, (int)servinfo->ai_addrlen) == SOCKET_ERROR) 
    { 
     int error = WSAGetLastError(); 
     printf("Connect error: ", error); 
    } 
} 

在这里,从侦听传入连接服务器的代码:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
// WINDOWS SETUP 
WSAData wsaData; 
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) 
{ 
    fprintf(stderr, "WSAStartup failed.\n"); 
    exit(1); 
} 

// PREPARE TO LAUNCH 
int status; 
struct sockaddr_storage their_addr; 
socklen_t addr_size; 
int sockfd, new_fd = 0; 

struct addrinfo hints; 
struct addrinfo *servinfo; // will point to the results 

memset(&hints, 0, sizeof hints); // make sure the struct is empty 
hints.ai_family = AF_UNSPEC;  // don't care IPv4 or IPv6 
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets 
hints.ai_flags = AI_PASSIVE;  // fill in my IP for me 

if ((status = getaddrinfo(NULL, "80", &hints, &servinfo)) != 0) 
{ 
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status)); 
    getchar(); 
    exit(1); 
} 

// GET THE FILE DESCRIPTOR 
SOCKET mSocket = INVALID_SOCKET; 
mSocket = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); 

// WHAT PORT AM I ON 
bind(mSocket, servinfo->ai_addr, servinfo->ai_addrlen); 

int backlog = 2; 
listen(mSocket, backlog); 

// SERVER STARTED LISTENING SUCCESFULLY 
printf("Server is listenening...\n"); 

// ACCEPT 
printf("Server starts accepting clients...\n"); 
addr_size = sizeof their_addr; 
new_fd = accept(mSocket, (struct sockaddr*)&their_addr, &addr_size); 

printf("Server ended"); 
getchar(); 

// lose the pesky "Address already in use" error message 
char yes='1'; 

if (setsockopt(mSocket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { 
    perror("setsockopt"); 
    exit(1); 
} 

return 0; 
} 

欢迎任何帮助!在此先感谢

+0

启动服务器后,用netstat,你看到服务器运行起来? –

+0

似乎没有出现80端口没有。 – Dries

回答

4

在客户端:

  1. 调用connect()之前不叫WSACleanup()
  2. 您在getaddrinfo()上没有执行任何错误处理。
  3. 您没有设置ai_flags以匹配您的输入值(如AI_NUMERICHOST)。
  4. 您不能释放getaddrinfo()返回的内存。
  5. 您没有考虑到您正在指定AF_UNSPECgetaddrinfo(),因此它可能会返回多个地址。你应该尝试连接所有的人,直到一个成功。

试试这个:

void Base::Connect(string ip, string port) 
{ 
    int status, error; 
    SOCKET ConnectSocket = INVALID_SOCKET; 
    struct addrinfo hints = {0}; 
    struct addrinfo *servinfo; // will point to the results 

    hints.ai_family = AF_UNSPEC;  // don't care IPv4 or IPv6 
    hints.ai_socktype = SOCK_STREAM; // TCP stream sockets 
    hints.ai_flags = AI_NUMERICHOST; // parse an IP address 
    //hints.ai_flags |= AI_NUMERICSERV; // parse a port number (not supported on Windows) 

    // get ready to connect 
    status = getaddrinfo(ip.c_str(), port.c_str(), &hints, &servinfo); 
    if (status != 0) 
    { 
     printf("getaddrinfo error: (%d) %s\n", status, gai_strerror(status)); 
     return; 
    } 

    addrinfo *addr = servinfo; 
    do 
    { 
     // Socket Setup 
     ConnectSocket = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 
     if (ConnectSocket == INVALID_SOCKET) 
     { 
      printf("socket error: %d\n", WSAGetLastError()); 
     } 
     else 
     { 
      // Connect 
      if (connect(ConnectSocket, addr->ai_addr, addr->ai_addrlen) != SOCKET_ERROR) 
      { 
       printf("connected to server\n"); 
       break; 
      } 

      printf("connect error: %d\n", WSAGetLastError()); 

      closesocket(ConnectSocket); 
      ConnectSocket = INVALID_SOCKET; 
     } 

     addr = addr->ai_next; 
    } 
    while (addr != NULL); 

    freeaddrinfo(servinfo); 

    if (ConnectSocket == INVALID_SOCKET) 
     printf("unable to connect to server\n"); 
} 

在服务器端:

  1. 你没有做任何错误处理上socket()bind()listen()
  2. SO_REUSEADDR必须在致电bind()之前启用,而不是之后。而且你甚至没有正确地启用它。
  3. 您不能释放getaddrinfo()返回的内存。

试试这个:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    // WINDOWS SETUP 
    WSAData wsaData; 
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) 
    { 
     fprintf(stderr, "WSAStartup failed.\n"); 
     exit(1); 
    } 

    // PREPARE TO LAUNCH 
    int status; 
    struct sockaddr_storage their_addr; 
    socklen_t addr_size; 
    SOCKET client; 

    struct addrinfo hints = {0}; 
    struct addrinfo *servinfo; // will point to the results 

    hints.ai_family = AF_UNSPEC;  // don't care IPv4 or IPv6 
    hints.ai_socktype = SOCK_STREAM; // TCP stream sockets 
    hints.ai_flags = AI_PASSIVE;  // fill in my IP for me 
    //hints.ai_flags |= AI_NUMERICSERV; // parse a port number (not supported on Windows) 

    status = getaddrinfo(NULL, "80", &hints, &servinfo); 
    if (status != 0) 
    { 
     fprintf(stderr, "getaddrinfo error: (%d) %s\n", status, gai_strerror(status)); 
     getchar(); 
     exit(1); 
    } 

    // optional, loop through servinfo creating a separate 
    // listening socket for each address reported... 

    // GET THE FILE DESCRIPTOR 
    SOCKET mSocket = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); 
    if (mSocket == INVALID_SOCKET) 
    { 
     fprintf(stderr, "socket error: %d\n", WSAGetLastError()); 
     freeaddrinfo(servinfo); 
     closesocket(mSocket); 
     getchar(); 
     exit(1); 
    } 

    // lose the pesky "Address already in use" error message 
    BOOL yes = TRUE; 
    if (setsockopt(mSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "setsockopt error: %d\n", WSAGetLastError()); 
     freeaddrinfo(servinfo); 
     closesocket(mSocket); 
     getchar(); 
     exit(1); 
    } 

    // WHAT PORT AM I ON 
    if (bind(mSocket, servinfo->ai_addr, servinfo->ai_addrlen) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "bind error: %d\n", WSAGetLastError()); 
     freeaddrinfo(servinfo); 
     closesocket(mSocket); 
     getchar(); 
     exit(1); 
    } 

    freeaddrinfo(servinfo); 

    int backlog = 2; 
    if (listen(mSocket, backlog) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "listen error: %d\n", WSAGetLastError()); 
     closesocket(mSocket); 
     getchar(); 
     exit(1); 
    } 

    // SERVER STARTED LISTENING SUCCESFULLY 
    printf("Server is listening...\n"); 

    // ACCEPT 
    addr_size = sizeof their_addr; 
    client = accept(mSocket, (struct sockaddr*)&their_addr, &addr_size); 
    if (client == INVALID_SOCKET) 
    { 
     fprintf(stderr, "accept error: %d\n", WSAGetLastError()); 
    } 
    else 
    { 
     char ip[NI_MAXHOST] = {0}; 
     char port[NI_MAXSERV] = {0}; 

     status = getnameinfo((struct sockaddr*)&their_addr, addr_size, ip, NI_MAXHOST, port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV); 
     if (status == 0) 
      printf("Client connected from %s:%s\n", ip, port); 
     else 
      printf("Client connected. getnameinfo error: (%d) %s\n", status, gai_strerror(status)); 

     //... 

     closesocket(client); 
    }   

    closesocket(mSocket); 
    printf("Server ended"); 

    getchar(); 

    return 0; 
} 
+0

我改变了一切。感谢您为我所做的所有代码!不幸的是,我仍然在尝试连接时出现错误10061。 (仍然使用端口80和ip 127.0.0.1来连接) – Dries

相关问题