2010-11-22 23 views
14

Tôi vừa mới bắt đầu tìm hiểu winsock thông qua sách hướng dẫn "Lập trình Beej để lập trình mạng". Tôi đang lập trình dưới các cửa sổ và chạy nó thông qua gcc. Đây chỉ là một khởi đầu để viết chương trình máy chủ đầu tiên của tôi nhưng nó mang lại cho tôi những lỗi này khi tôi cố gắng biên dịch.lỗi biên dịch winsock, nó không thể tìm thấy cấu trúc addrinfo và một số chức năng liên quan

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

đây là những lỗi Tôi nhận

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. 

nên không phải là cấu trúc và chức năng được quy định tại một trong hai windows.h hoặc winsock.h ?.

SOLUTION

EDIT cho bất cứ ai tình cờ về vấn đề này, thêm

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

ở đầu nguồn của bạn nếu getaddrinfo nói rằng không khai báo của nó.

+2

hey cảm ơn vì điều đó #define _WIN32_WINNT 0x501 đã lưu cho tôi một số sự cố :) – Lefteris

+0

Không có vấn đề :-). – silent

+0

Tôi đang ở trên Win7, VS2015, và cho đến nay tôi chưa phải thêm câu lệnh #define, nhưng DID cần thêm câu lệnh #include. Công cụ xây dựng của tôi có thể hơi lạ vì tôi đang làm việc với một bộ thư viện cũ. – Andrew

Trả lời

7

Bạn có thể muốn #include <ws2tcpip.h>. Hãy nhớ rằng trước khi Stack Overflow, Google là bạn của bạn cho loại câu hỏi này: bạn sẽ nhận được câu trả lời ngay lập tức từ MSDN!

+0

cảm ơn vì điều đó, Nhưng nó vẫn không thấy getaddrinfo vì một lý do nào đó? – silent

+0

tìm thấy những gì còn thiếu :) nvm – silent

+0

@ sil3ent nó là gì? – icecrime

0

Cẩn thận! Bao gồm của bạn là sai. Vấn đề là windows.h đã bao gồm winsock.hwinsock2.h sau đó xác định lại một số cấu trúc và chức năng dẫn đến số lượng lỗi biên dịch lớn. Di chuyển các windows.h bao gồm bên dưới winsock2.h bao gồm hoặc chỉ xóa windows.h bao gồm hoàn toàn, winsock2.h bao gồm windows.h.

+0

Windows.h bao gồm winsock.h, để sử dụng winsock2, bạn cần sử dụng câu lệnh #define WIN32_LEAN_AND_MEAN. WinSock2 có mã không tương thích với winsock.h. Vì vậy, để sử dụng windows.h và WInSock2.h, hãy sử dụng #define. Có một LƯU Ý nửa chừng xuống trang này thảo luận chi tiết hơn về điều này: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx – Andrew

1

MSDN nói rằng chúng ta nên #include <ws2tcpip.h>, nhưng trong ws2tcpip.h tôi tìm thấy đoạn mã này:

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

điều này có nghĩa, rằng _WIN32_WINNT được xác định thấp hơn _WIN32_WINNT_WINXP, nhưng khi tôi đã cố gắng bao gồm wspiapi.h, tôi đã nhận "no such file or directory". Tôi đoán là, đây là lỗi của MinGW, nơi các phần khác nhau của thư viện có các phiên bản không phù hợp. Bạn phải #define _WIN32_WINNT _WIN32_WINNT_WINXP trên của riêng bạn, trước khi đưa ws2tcpip.h

0

này đang làm việc cho tôi:

#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

tôi đã có thể có được điều này để làm việc với những điều sau đây bao gồm, pragma, và xác định ...

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

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

danh mục cần thiết bao gồm cho câu trả lời này được trình bày trong một bài viết Microsoft: Winsock Includes

Các vấn đề liên quan