简体   繁体   English

winsock编译错误,找不到addrinfo结构和一些相关函数

[英]winsock compiling error, it cant find the addrinfo structures and some relating functions

I've just started learning winsock through the "Beej's guide to.network programming" book.我刚刚开始通过“Beej 的网络编程指南”一书学习 winsock。 I'm programming under windows and running it through gcc. This is just a start to writing my first server program but it gives me these errors when I try to compile.我在 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;
}

these are the errors I'm receiving这些是我收到的错误

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.

Shouldn't the structures and functions be defined in either windows.h or winsock.h?.结构和函数不应该在 windows.h 或 winsock.h 中定义吗?

SOLUTION解决方案

EDIT to anyone who stumbles on this, add编辑任何偶然发现此问题的人,添加

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

at the top of your source if getaddrinfo says that its undeclared.如果 getaddrinfo 说它未声明,则在源代码的顶部。

You probably want to #include <ws2tcpip.h> . 你可能想要#include <ws2tcpip.h> Remember that before Stack Overflow, Google is your friend for this kind of questions : you will get immediate answers from MSDN ! 请记住,在Stack Overflow之前, Google是您提出这类问题的朋友:您将从MSDN获得即时答案!

MSDN says we should #include <ws2tcpip.h> , but in ws2tcpip.h i found this piece of code: 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) */

this means, that _WIN32_WINNT is defined lower than _WIN32_WINNT_WINXP , but when i tried include wspiapi.h , i got "no such file or directory" . 这意味着, _WIN32_WINNT的定义低于_WIN32_WINNT_WINXP ,但是当我尝试包含wspiapi.h ,我得到了"no such file or directory" My guess is, this is an fault of MinGW, where different parts of the library have inconsistent versions. 我的猜测是,这是MinGW的错,其中库的不同部分具有不一致的版本。 You have to #define _WIN32_WINNT _WIN32_WINNT_WINXP on your own, before including ws2tcpip.h 在包含ws2tcpip.h之前,你必须自己#define _WIN32_WINNT _WIN32_WINNT_WINXP ws2tcpip.h

This is working for me: 这对我有用:

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

I was able to get this to work with the following includes, pragma, and defines... 我能够使用以下包含,pragma和定义......

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

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

The list of necessary includes for this answer are shown in a Microsoft article: Winsock Includes 此答案的必要包含列表显示在Microsoft文章中: Winsock Includes

Beware! 谨防! Your includes are wrong. 你的包含是错误的。 The problem is that windows.h already includes winsock.h and winsock2.h then re-defines some structures and functions resulting in huge number of compilation errors. 问题是, windows.h已经包括winsock.hwinsock2.h然后重新定义了一些结构和导致编译错误的大量功能。 Move the windows.h include below the winsock2.h include, or just remove the windows.h include altogether, winsock2.h includes windows.h . 移动windows.h包含winsock2.h下面的include,或者只删除windows.h包含的一个, winsock2.h包含windows.h

In my case, I added struct when declaring sockaddr_in .就我而言,我在声明sockaddr_in时添加了struct

changed:改变了:

sockaddr_in m_sockAddr;

to

struct sockaddr_in m_sockAddr;

also,还,

bind(sock, (sockaddr*)&m_sockAddr, sizeof(m_sockAddrLsng ))

to

bind(m_sockLsng, (struct sockaddr*)&m_sockAddr, sizeof(m_sockAddr))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM