17

I've just started learning winsock through the "Beej's guide to network programming" book. 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.

/* 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?.

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.

silent
  • 2,836
  • 10
  • 47
  • 73
  • 4
    hey thanks for that #define _WIN32_WINNT 0x501 saved me some trouble :) – Lefteris Apr 06 '12 at 04:38
  • I'm on Win7, VS2015, and so far I haven't had to add the #define statement, but DID need to add the #include statement. My build env may be a little weird since I'm working with a set of old libraries. – Andrew Oct 03 '16 at 21:35

6 Answers6

8

You probably want to #include <ws2tcpip.h>. Remember that before Stack Overflow, Google is your friend for this kind of questions : you will get immediate answers from MSDN !

icecrime
  • 74,451
  • 13
  • 99
  • 111
1

MSDN says we should #include <ws2tcpip.h>, but in ws2tcpip.h i found this piece of code:

#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". My guess is, this is an fault of MinGW, where different parts of the library have inconsistent versions. You have to #define _WIN32_WINNT _WIN32_WINNT_WINXP on your own, before including ws2tcpip.h

Youda008
  • 1,788
  • 1
  • 17
  • 35
0

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();
}    
MD XF
  • 7,860
  • 7
  • 40
  • 71
Roberto Santos
  • 606
  • 1
  • 7
  • 11
0

I was able to get this to work with the following includes, pragma, and defines...

#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

MD XF
  • 7,860
  • 7
  • 40
  • 71
Andrew
  • 1,423
  • 1
  • 17
  • 26
0

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. Move the windows.h include below the winsock2.h include, or just remove the windows.h include altogether, winsock2.h includes windows.h.

wilx
  • 17,697
  • 6
  • 59
  • 114
  • Windows.h includes winsock.h, in order to use winsock2, you need to use the #define WIN32_LEAN_AND_MEAN statement. WinSock2 has code that is not compatible with winsock.h. So, in order to use windows.h and WInSock2.h, use the #define. There is a NOTE halfway down this page that discusses this in better detail: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx – Andrew Oct 03 '16 at 21:47
0

In my case, I added struct when declaring sockaddr_in.

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))

Zrn-dev
  • 99
  • 5