Hallo,
hab mit Dev-C++ 4.9.8.0 ein prob, das bestimmt leicht zu lösen ist. Ein kleines kopiertes Serverprogramm wird nicht kompiliert aufgrund o.g. Linker Errors.
----CODE-- BEGIN ----
/* httpserv.c
* Demoprogramm zur Programmierung von Netzwerkservern
* Es wird ein simpler http Server implementiert,
* der ausschließlich GET requests bearbeiten kann */
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#ifdef _WIN32
/* Headerfiles für Windows */
#include <winsock.h>
#include <io.h>
#else
/* Headerfiles für Unix/Linux */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define closesocket(s) close(s)
#endif
/* http requests werden normalerweise auf Port 80
* vom Server beantwortet */
#define HTTP_PORT 80
static void serv_request( int in, int out, char* rootpath);
/****************** MAIN *********************/
int main( int argc, char **argv)
{
struct sockaddr_in server, client;
int sock, fd;
int len;
#ifdef _WIN32
/* Initialisiere TCP für Windows ("winsock") */
short wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup (wVersionRequested, &wsaData) != 0) {
fprintf( stderr, "Failed to init windows sockets\n");
exit(1);
}
#endif
/* Teste auf Kommadozeilenargument "documentroot" */
if (2 != argc) {
fprintf( stderr, "usage: httpserv documentroot\n");
exit(1);
}
/* Erzeuge das Socket */
sock = socket( PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror( "failed to create socket");
exit(1);
}
/* Erzeuge die Socketadresse des Servers
* Sie besteht aus Typ und Portnummer */
memset( &server, 0, sizeof (server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl( INADDR_ANY);
server.sin_port = htons( HTTP_PORT);
/* Erzeuge die Bindung an die Serveradresse
* (d.h. an einen bestimmten Port) */
if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
perror( "can't bind socket");
exit(1);
}
/* Teile dem Socket mit, dass Verbindungswünsche
* von Clients entgegengenommen werden */
listen( sock, 5);
Nun kommt der interessante Teil: Die Serverhauptschleife. Hier wird die Funktion accept() aufgerufen. Diese blockiert solange, bis ein Client seinerseits ein connect() mit Adresse und Portnummer unseres Servers aufruft. Dann liefert accept() einen neuen Socket zurück, über den der Datentransfer mit dem Client in beiden Richtungen (Daten vom Client, Daten zum Client) ablaufen kann. Dieser Datenaustausch muss in unserem Beispiel natürlich den Regeln von HTTP folgen und wurde komplett in die Funktion serv_request() ausgelagert. Nach Beendigung der Verbindung mit dem Client ruft der Server wiederum accept() auf, um weitere Verbindungswünsche abarbeiten zu können:
/* Bearbeite die Verbindungswünsche von Clients
* in einer Endlosschleife
* Der Aufruf von accept() blockiert solange,
* bis ein Client Verbindung aufnimmt */
for (;
{
len = sizeof( client);
fd = accept( sock, (struct sockaddr*)&client, &len);
if (fd < 0) {
perror( "accept failed");
exit(1);
}
/* Bearbeite den http Request */
serv_request( fd, fd, argv[1]);
/* Schließe die Verbindung */
closesocket( fd);
}
}
Die Funktion serv_request() zur serverseitigen Implementierung von HTTP wurde aus Platzgründen auf ein Minimum beschränkt. Sie kann ausschließlich GET Requests bearbeiten, kennt nur HTML-Dateien (kann also weder GIF- noch JPEG-Images übertragen) und hat nur eine rudimentäre Fehlerbehandlung:
/*
* serv_request
* Bearbeite den auf in ankommenden http request
* Die zu sendenden Daten werden auf out ausgegeben
*/
static void serv_request( int in, int out, char* rootpath)
{
char buffer[8192];
char *b, *l, *le;
int count, totalcount;
char url[256];
char path[256];
int fd;
int eoh = 0;
b = buffer;
l = buffer;
totalcount = 0;
*url = '\0';
while ( (count = recv( in, b, sizeof(buffer) - totalcount, 0)) > 0) {
totalcount += count;
b += count;
while (l < b) {
le = l;
while (le < b && *le != '\n' && *le != '\r') ++le;
if ('\n' == *le || '\r' == *le) {
*le = '\0';
printf ("Header line = \"%s\"\n", l);
sscanf( l, "GET %255s HTTP/", url);
if (strlen(l)) eoh = 1;
l = le + 1;
}
}
if (eoh) break;
}
if ( strlen(url)) {
printf( "got request: GET %s\n", url);
sprintf(path, "%s/%s", rootpath, url);
fd = open( path, O_RDONLY);
if (fd > 0) {
sprintf( buffer, "HTTP/1.0 200 OK\nContent-Type: text/html\n\n");
send( out, buffer, strlen(buffer), 0);
do {
count = read( fd, buffer, sizeof(buffer));
send( out, buffer, count, 0);
printf(".");
fflush(stdout);
} while (count > 0);
close( fd);
printf("finished request: GET %s\n", url);
}
else {
sprintf( buffer, "HTTP/1.0 404 Not Found\n\n");
send( out, buffer, strlen(buffer), 0);
}
}
else {
sprintf( buffer, "HTTP/1.0 501 Method Not Implemented\n\n");
send( out, buffer, strlen(buffer), 0);
}
}
----CODE ---ENDE ----
FEHLER:
[Linker Error] undefined reference to 'wsastartup@8'
und noch einege andere nach demselben muster
Was muss ich denn noch tun?
hab mit Dev-C++ 4.9.8.0 ein prob, das bestimmt leicht zu lösen ist. Ein kleines kopiertes Serverprogramm wird nicht kompiliert aufgrund o.g. Linker Errors.
----CODE-- BEGIN ----
/* httpserv.c
* Demoprogramm zur Programmierung von Netzwerkservern
* Es wird ein simpler http Server implementiert,
* der ausschließlich GET requests bearbeiten kann */
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#ifdef _WIN32
/* Headerfiles für Windows */
#include <winsock.h>
#include <io.h>
#else
/* Headerfiles für Unix/Linux */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define closesocket(s) close(s)
#endif
/* http requests werden normalerweise auf Port 80
* vom Server beantwortet */
#define HTTP_PORT 80
static void serv_request( int in, int out, char* rootpath);
/****************** MAIN *********************/
int main( int argc, char **argv)
{
struct sockaddr_in server, client;
int sock, fd;
int len;
#ifdef _WIN32
/* Initialisiere TCP für Windows ("winsock") */
short wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup (wVersionRequested, &wsaData) != 0) {
fprintf( stderr, "Failed to init windows sockets\n");
exit(1);
}
#endif
/* Teste auf Kommadozeilenargument "documentroot" */
if (2 != argc) {
fprintf( stderr, "usage: httpserv documentroot\n");
exit(1);
}
/* Erzeuge das Socket */
sock = socket( PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror( "failed to create socket");
exit(1);
}
/* Erzeuge die Socketadresse des Servers
* Sie besteht aus Typ und Portnummer */
memset( &server, 0, sizeof (server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl( INADDR_ANY);
server.sin_port = htons( HTTP_PORT);
/* Erzeuge die Bindung an die Serveradresse
* (d.h. an einen bestimmten Port) */
if (bind( sock, (struct sockaddr*)&server, sizeof( server)) < 0) {
perror( "can't bind socket");
exit(1);
}
/* Teile dem Socket mit, dass Verbindungswünsche
* von Clients entgegengenommen werden */
listen( sock, 5);
Nun kommt der interessante Teil: Die Serverhauptschleife. Hier wird die Funktion accept() aufgerufen. Diese blockiert solange, bis ein Client seinerseits ein connect() mit Adresse und Portnummer unseres Servers aufruft. Dann liefert accept() einen neuen Socket zurück, über den der Datentransfer mit dem Client in beiden Richtungen (Daten vom Client, Daten zum Client) ablaufen kann. Dieser Datenaustausch muss in unserem Beispiel natürlich den Regeln von HTTP folgen und wurde komplett in die Funktion serv_request() ausgelagert. Nach Beendigung der Verbindung mit dem Client ruft der Server wiederum accept() auf, um weitere Verbindungswünsche abarbeiten zu können:
/* Bearbeite die Verbindungswünsche von Clients
* in einer Endlosschleife
* Der Aufruf von accept() blockiert solange,
* bis ein Client Verbindung aufnimmt */
for (;

len = sizeof( client);
fd = accept( sock, (struct sockaddr*)&client, &len);
if (fd < 0) {
perror( "accept failed");
exit(1);
}
/* Bearbeite den http Request */
serv_request( fd, fd, argv[1]);
/* Schließe die Verbindung */
closesocket( fd);
}
}
Die Funktion serv_request() zur serverseitigen Implementierung von HTTP wurde aus Platzgründen auf ein Minimum beschränkt. Sie kann ausschließlich GET Requests bearbeiten, kennt nur HTML-Dateien (kann also weder GIF- noch JPEG-Images übertragen) und hat nur eine rudimentäre Fehlerbehandlung:
/*
* serv_request
* Bearbeite den auf in ankommenden http request
* Die zu sendenden Daten werden auf out ausgegeben
*/
static void serv_request( int in, int out, char* rootpath)
{
char buffer[8192];
char *b, *l, *le;
int count, totalcount;
char url[256];
char path[256];
int fd;
int eoh = 0;
b = buffer;
l = buffer;
totalcount = 0;
*url = '\0';
while ( (count = recv( in, b, sizeof(buffer) - totalcount, 0)) > 0) {
totalcount += count;
b += count;
while (l < b) {
le = l;
while (le < b && *le != '\n' && *le != '\r') ++le;
if ('\n' == *le || '\r' == *le) {
*le = '\0';
printf ("Header line = \"%s\"\n", l);
sscanf( l, "GET %255s HTTP/", url);
if (strlen(l)) eoh = 1;
l = le + 1;
}
}
if (eoh) break;
}
if ( strlen(url)) {
printf( "got request: GET %s\n", url);
sprintf(path, "%s/%s", rootpath, url);
fd = open( path, O_RDONLY);
if (fd > 0) {
sprintf( buffer, "HTTP/1.0 200 OK\nContent-Type: text/html\n\n");
send( out, buffer, strlen(buffer), 0);
do {
count = read( fd, buffer, sizeof(buffer));
send( out, buffer, count, 0);
printf(".");
fflush(stdout);
} while (count > 0);
close( fd);
printf("finished request: GET %s\n", url);
}
else {
sprintf( buffer, "HTTP/1.0 404 Not Found\n\n");
send( out, buffer, strlen(buffer), 0);
}
}
else {
sprintf( buffer, "HTTP/1.0 501 Method Not Implemented\n\n");
send( out, buffer, strlen(buffer), 0);
}
}
----CODE ---ENDE ----
FEHLER:
[Linker Error] undefined reference to 'wsastartup@8'
und noch einege andere nach demselben muster
Was muss ich denn noch tun?