2010-11-22 11 views
14

Właśnie zacząłem uczyć się winsock poprzez książkę "Beej's guide to network programming". Programuję pod Windowsem i uruchamiam go przez gcc. To dopiero początek pisania mojego pierwszego programu serwera, ale daje mi te błędy, gdy próbuję skompilować.Błąd kompilacji winsock, nie można znaleźć struktur addrinfo i niektórych powiązanych funkcji

/* 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; 
} 

są to błędy jestem otrzymujących

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. 

nie powinien struktury i funkcje zostać zdefiniowane w obu windows.h lub winsock.h ?.

ROZWIĄZANIE

EDIT każdemu, kto natyka się na tym, dodać

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

na górze źródła jeśli getaddrinfo mówi, że jego nielegalna.

+2

hej dzięki za to #define _WIN32_WINNT 0x501 zaoszczędziło mi trochę kłopotu :) – Lefteris

+0

Żadnych problemów :-). – silent

+0

Jestem na Win7, VS2015 i do tej pory nie musiałem dodawać instrukcji #define, ale DID musi dodać instrukcję #include. Moja kompilacja może być trochę dziwna, ponieważ pracuję z zestawem starych bibliotek. – Andrew

Odpowiedz

7

Prawdopodobnie chcesz #include <ws2tcpip.h>. Pamiętaj, że przed Stack Overflow, Google jest Twoim przyjacielem w tego rodzaju pytaniach: otrzymasz natychmiastowe odpowiedzi od MSDN!

+0

dzięki za to, ale nadal nie widzi getaddrinfo z jakiegoś powodu? – silent

+0

znaleziono czego brakowało :) nvm – silent

+0

@ sil3ent co to było? – icecrime

0

Uwaga! Twoje załączniki są nieprawidłowe. Problem polega na tym, że windows.h zawiera już winsock.h i winsock2.h, a następnie ponownie definiuje niektóre struktury i funkcje powodujące ogromną liczbę błędów kompilacji. Przenieś kompilacje windows.h pod składankę winsock2.h lub całkowicie usuń windows.h, winsock2.h zawiera windows.h.

+0

Windows.h zawiera winsock.h, aby użyć winsock2, musisz użyć instrukcji #define WIN32_LEAN_AND_MEAN. WinSock2 ma kod, który nie jest kompatybilny z winsock.h. Aby więc użyć windows.h i WInSock2.h, użyj #define. W połowie tej strony znajduje się UWAGA, które omawia tę sprawę bardziej szczegółowo: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx – Andrew

1

MSDN mówi, że powinniśmy #include <ws2tcpip.h>, ale w ws2tcpip.h znalazłem ten kawałek kodu:

#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) */ 

Oznacza to, że _WIN32_WINNT definiuje niższy niż _WIN32_WINNT_WINXP, ale gdy próbowałem to wspiapi.h, mam "no such file or directory". Zgaduję, że jest to wina MinGW, gdzie różne części biblioteki mają niespójne wersje. Trzeba #define _WIN32_WINNT _WIN32_WINNT_WINXP na własną rękę, przed tym ws2tcpip.h

0

To działa dla mnie:

#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

udało mi się uzyskać to do pracy z poniższych obejmuje Pragma i definiuje ...

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

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

lista zawiera niezbędne dla tej odpowiedzi przedstawiono w artykule Microsoft: Winsock Includes

Powiązane problemy