【问题标题】:winsock compiling error, it cant find the addrinfo structures and some relating functionswinsock编译错误,找不到addrinfo结构和一些相关函数
【发布时间】:2010-11-22 06:56:58
【问题描述】:

我刚刚开始通过“Beej 网络编程指南”一书开始学习winsock。我在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中定义吗?

解决方案

编辑 对于任何偶然发现此问题的人,请添加

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

如果 getaddrinfo 说它未声明,则在源代码的顶部。

【问题讨论】:

  • 嘿,感谢#define _WIN32_WINNT 0x501 为我节省了一些麻烦:)
  • 我在Win7,VS2015上,到目前为止我还没有添加#define语句,但是需要添加#include语句。我的构建环境可能有点奇怪,因为我正在使用一组旧库。

标签: c++ gcc winsock


【解决方案1】:

您可能想#include &lt;ws2tcpip.h&gt;。请记住,在 Stack Overflow 之前,Google 是您这类问题的朋友:您将立即从 MSDN 获得答案!

【讨论】:

  • 谢谢,但由于某种原因它仍然看不到 getaddrinfo?
  • 需要加#define _WIN32_WINNT 0x501,显然getaddrinfo有不同的版本。
  • 让我们将这个细节添加到这个答案中,而不是问题中,嗯?
【解决方案2】:

MSDN 说我们应该#include &lt;ws2tcpip.h&gt;,但在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

【讨论】:

    【解决方案3】:

    当心!您的包含错误。问题是windows.h 已经包含winsock.hwinsock2.h 然后重新定义了一些结构和函数导致大量编译错误。将windows.h 包含在winsock2.h 包含下方,或者干脆将windows.h 包含删除,winsock2.h 包含windows.h

    【讨论】:

    • Windows.h 包含winsock.h,要使用winsock2,需要使用#define WIN32_LEAN_AND_MEAN 语句。 WinSock2 的代码与 winsock.h 不兼容。因此,为了使用 windows.h 和 WInSock2.h,请使用#define。本页中间有一个注释,更详细地讨论了这一点:msdn.microsoft.com/en-us/library/windows/desktop/…
    【解决方案4】:

    我能够让它与以下包含、编译指示和定义一起使用...

    #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 Includes

    【讨论】:

      【解决方案5】:

      这对我有用:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多