# [Linker Error] undefined reference to..



## srpcool (6. April 2004)

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?


----------



## Kachelator (6. April 2004)

ws2_32.lib dazulinken? Da ist's drin.


----------



## srpcool (7. April 2004)

ok, die ist nun unter "Projekt-Optionen" -> "Parameter"->"Bibl-Obj hinzufügen" eingefügt worden.

Nun meldet er folgenden Fehler:
"File Format not recognized"

nun weiß ich leider immer noch nicht weiter...
was muss ich nun machen?


----------



## Kachelator (7. April 2004)

Ich kenne mich mit Dev-C++ leider nicht aus, deshalb habe ich bisher noch nichts dazu gesagt. Ich habe zwar im Netz nach der Fehlermeldung gesucht, bin aber dadurch nicht schlauer geworden - vermutlich, weil ich die IDE nicht kenne. Treffer hatte ich eine Menge.
Vielleicht könntest du mal selbst versuchen, bei Google Webseiten dazu zu finden. Ich habe "File Format not recognized" als Suchbegriff verwendet.


----------

