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. 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;
}
ret开发者_如何学Gourn 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.
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 !
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
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
.
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
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();
}
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))
精彩评论