c++ gcc winsock

c++ - Error de compilación de winsock, no puede encontrar las estructuras addrinfo y algunas funciones relacionadas



gcc (5)

Acabo de empezar a aprender winsock a través del libro "Guía de Beej para la programación en red". Estoy programando bajo Windows y ejecutándolo a través de gcc. Esto es solo un comienzo para escribir mi primer programa de servidor, pero me da estos errores cuando intento compilar.

/* 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 definirse las estructuras y funciones en windows.h o winsock.h?

SOLUCIÓN

EDITAR a cualquier persona que tropieza con esto, agregue

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

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


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(); }


MSDN dice que deberíamos #include <ws2tcpip.h> , pero en ws2tcpip.h encontré este fragmento 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 bajo que _WIN32_WINNT_WINXP , pero cuando intenté incluir wspiapi.h , no obtuve "no such file or directory" . Mi conjetura es que esto es un error de MinGW, donde diferentes partes de la biblioteca tienen versiones inconsistentes. #define _WIN32_WINNT _WIN32_WINNT_WINXP por su cuenta, antes de incluir ws2tcpip.h


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


Pude lograr que esto funcionara con los siguientes objetos, 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 los incluidos necesarios para esta respuesta se muestra en un artículo de Microsoft: Winsock incluye


¡Tener cuidado! Tu inclusión está mal. El problema es que windows.h ya incluye winsock.h y winsock2.h continuación, redefine algunas estructuras y funciones, lo que winsock2.h gran cantidad de errores de compilación. Mueva windows.h include debajo de winsock2.h include, o simplemente elimine windows.h include en total, winsock2.h incluye windows.h .