Ошибка компиляции winsock, он не может найти структуры addrinfo и некоторые связанные функции - PullRequest
16 голосов
/ 22 ноября 2010

Я только начал изучать winsock из книги «Руководство Beej по сетевому программированию». Я программирую под Windows и запускаю его через gcc. Это только начало написания моей первой серверной программы, но при попытке компиляции я получаю эти ошибки.

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

это ошибки, которые я получаю

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.

Разве структуры и функции не должны быть определены ни в windows.h, ни в winsock.h?.

РЕШЕНИЕ

EDIT любому, кто сталкивается с этим, добавьте

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

вверху вашего источника, если getaddrinfo говорит, что он необъявлен.

Ответы [ 5 ]

7 голосов
/ 22 ноября 2010

Вы, вероятно, хотите #include <ws2tcpip.h>. Помните, что до переполнения стека Google является вашим другом для таких вопросов: вы получите немедленные ответы из MSDN!

1 голос
/ 09 июля 2014

MSDN говорит, что мы должны #include <ws2tcpip.h>, но в ws2tcpip.h я нашел этот фрагмент кода:

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

это означает, что _WIN32_WINNT определено ниже, чем _WIN32_WINNT_WINXP, но когда я попытался включить wspiapi.h, я получил "no such file or directory". Я предполагаю, что это ошибка MinGW, где разные части библиотеки имеют несовместимые версии. Вы должны #define _WIN32_WINNT _WIN32_WINNT_WINXP самостоятельно, прежде чем включить ws2tcpip.h

0 голосов
/ 04 октября 2016

Я смог заставить это работать со следующими включениями, прагмой и определениями ...

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

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

Список необходимых включений для этого ответа показан в статье Microsoft:Winsock Включает

0 голосов
/ 15 февраля 2015

Это работает для меня:

#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 голосов
/ 22 ноября 2010

Осторожно! Ваши предложения неверны. Проблема в том, что windows.h уже включает winsock.h и winsock2.h, а затем переопределяет некоторые структуры и функции, что приводит к огромному количеству ошибок компиляции. Переместите элемент windows.h ниже элемента winsock2.h или просто полностью удалите элемент windows.h, элемент winsock2.h включает windows.h.

...