2010-11-22 7 views
14

Acabo de empezar a aprender winsock a través del libro "Beej's guide to network programming". Estoy programando en Windows y ejecutándolo a través de gcc. Esto es solo el comienzo de la escritura de mi primer programa de servidor, pero me da estos errores cuando intento compilar.winsock error de compilación, no puede encontrar las estructuras addrinfo y algunas funciones relacionadas

/* Server */ 
#include <iostream> 
#include <windows.h> 
#include <winsock2.h> 
using namespace std; 

const int winsockVersion = 2; 
#define BACKLOG 10 
#define PORT 3000 


int main(void){ 

    WSADATA wsadata; 
    if (WSAStartup(MAKEWORD(winsockVersion,0),&wsadata) == 0){ 


     struct addrinfo hints, *res; 

     memset(&hints,0,sizeof hints); 
     hints.ai_family = AF_INET; 
     hints.ai_socktype = SOCK_STREAM; 
     hints.ai_flags = AI_PASSIVE; 

     if (getaddrinfo(NULL,PORT,&hints,&res) == 0){ 
      cout<<"-Call to get addrinfo successful!." << endl; 
     } 

     cout<<"res af_family" << res->ai_family << endl; 
    } 




    //clear stuff 
    if(WSACleanup() != 0){ 
     cout<<"-WSACleanup unsuccessful" << endl; 
    }else{ 
     cout<<"-WSACleanup successful" << endl; 
    } 


    return 0; 
} 

estos son los errores que estoy recibiendo

g++ -o server.exe server.cpp -lws2_32 
Process started >>> 
server.cpp: In function `int main()': 
server.cpp:20: error: aggregate `addrinfo hints' has incomplete type and cannot be defined 
server.cpp:25: error: `AI_PASSIVE' was not declared in this scope 
server.cpp:27: error: `getaddrinfo' was not declared in this scope 
server.cpp:31: error: invalid use of undefined type `struct addrinfo' 
server.cpp:20: error: forward declaration of `struct addrinfo' 
server.cpp:54:2: warning: no newline at end of file 
<<< Process finished. 

¿No deberían las estructuras y funciones se definirán en cualquiera windows.h o winsock.h ?.

SOLUCIÓN

EDITAR a cualquier persona que se topa con esto, añadir

#define _WIN32_WINNT 0x501 
#include <ws2tcpip.h> 

en la parte superior de la fuente si getaddrinfo dice que su no declarado.

+2

hola gracias por ese #define _WIN32_WINNT 0x501 me salvó algunos problemas :) – Lefteris

+0

Sin problemas :-). – silent

+0

Estoy en Win7, VS2015, y hasta ahora no he tenido que agregar la declaración #define, pero DID necesito agregar la declaración #include. Mi entorno de compilación puede ser un poco extraño ya que estoy trabajando con un conjunto de bibliotecas antiguas. – Andrew

Respuesta

7

Probablemente desee #include <ws2tcpip.h>. Recuerde que antes de Stack Overflow, Google es su amigo para este tipo de preguntas: ¡obtendrá respuestas inmediatas de MSDN!

+0

gracias por eso, pero todavía no ve getaddrinfo por alguna razón? – silent

+0

encontró lo que faltaba :) nvm – silent

+0

@ sil3ent ¿qué era? – icecrime

0

¡Cuidado! Sus inclusiones son incorrectas. El problema es que windows.h ya incluye winsock.h y winsock2.h y luego redefine algunas estructuras y funciones, lo que da como resultado una gran cantidad de errores de compilación. Mueva el windows.h incluya debajo del winsock2.h incluya, o simplemente elimine el windows.h incluya en total, winsock2.h incluye windows.h.

+0

Windows.h incluye winsock.h, para usar winsock2, debe usar la sentencia #define WIN32_LEAN_AND_MEAN. WinSock2 tiene un código que no es compatible con winsock.h. Entonces, para usar windows.hy WInSock2.h, use #define. Hay una NOTA en la mitad de esta página que trata este tema con mayor detalle: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx – Andrew

1

MSDN dice que debemos hacerlo #include <ws2tcpip.h>, pero en ws2tcpip.h he encontrado este pedazo de código:

#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) 
/** 
* For WIN2K the user includes wspiapi.h for these functions. 
*/ 
void WSAAPI freeaddrinfo (struct addrinfo*); 
int WSAAPI getaddrinfo (const char*,const char*,const struct addrinfo*, 
       struct addrinfo**); 
int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, 
      char*,DWORD,int); 
#endif /* (_WIN32_WINNT >= _WIN32_WINNT_WINXP) */ 

esto significa, que _WIN32_WINNT se define más baja que _WIN32_WINNT_WINXP, pero cuando he intentado incluir wspiapi.h, me dieron "no such file or directory". Mi suposición es que esto es un error de MinGW, donde diferentes partes de la biblioteca tienen versiones inconsistentes. Tienes que #define _WIN32_WINNT _WIN32_WINNT_WINXP por su cuenta, antes de incluir ws2tcpip.h

0

Esto es trabajo para mí:

#include <winsock2.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

#define DEFAULT_PORT 80 

void error_die(const char *s) 
{ 
    fprintf(stderr, "Error: %s failed with error %d\n", s, WSAGetLastError()); 
    WSACleanup(); 
    exit(EXIT_FAILURE); 
} 

int main(int argc, char **argv) 
{ 
    char response[] = "HTTP/1.1 200 OK\r\n" 
    "Content-Type: text/html; charset=UTF-8\r\n\r\n" 
    "<!DOCTYPE html><html><head><title>Hello World</title></head>" 
    "<body><h1>Hello world!</h1></body></html>\r\n"; 

    char buf[4096]; 
    int msg_len, addr_len; 
    struct sockaddr_in local, client_addr; 

    SOCKET sock, msg_sock; 
    WSADATA wsaData; 

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError()); 
     WSACleanup(); 
     return -1; 
    } 

    // Fill in the address structure 
    local.sin_family  = AF_INET; 
    local.sin_addr.s_addr = INADDR_ANY; 
    local.sin_port   = htons(DEFAULT_PORT); 

    sock = socket(AF_INET, SOCK_STREAM, 0); //TCP socket 

    if (sock == INVALID_SOCKET) 
     error_die("socket()"); 

    if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) 
     error_die("bind()"); 

    if (listen(sock, 5) == SOCKET_ERROR) // wait for connection 
     error_die("listen()"); 

    printf("Waiting for connection...\n"); 

    while (1) 
    { 
     addr_len = sizeof(client_addr); 
     msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len); 

     if (msg_sock == INVALID_SOCKET || msg_sock == -1) 
      error_die("accept()"); 

     printf("Accepted connection from %s, port %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port)); 

     msg_len = recv(msg_sock, buf, sizeof(buf), 0); 

     printf("Bytes Received: %d, message: %s from %s\n", msg_len, buf, inet_ntoa(client_addr.sin_addr)); 

     msg_len = send(msg_sock, response, sizeof(response)-1 , 0); 

     if (msg_len == SOCKET_ERROR) 
      error_die("send()"); 

     if (!msg_len) 
     { 
      printf("Client closed connection\n"); 
      closesocket(msg_sock); 
      WSACleanup(); 
      return -1; 
     } 

     closesocket(msg_sock); 
    } 

    WSACleanup(); 
}  
0

yo era capaz de conseguir esto para trabajar con la siguiente incluye, pragma, y ​​define ...

#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <stdio.h> 

#pragma comment(lib, "ws2_32.lib") 

La lista de necesaria incluye, por esta respuesta se muestran en un artículo de Microsoft: Winsock Includes

Cuestiones relacionadas