C++ Einfache "C++-Klasse" kompilieren

tuxIt!

Cadet 3rd Year
Registriert
Sep. 2010
Beiträge
42
Hallo,

seit einiger Zeit versuche ich mit Code::Blocks die drei Dateien (socket.h, socket.cpp, main.cpp) von http://www.adp-gmbh.ch/win/misc/sockets.html zu kompilieren und daraus eine exe-Datei zu erzeugen, die man ausführen kann.

Leider klappt das irgendwie nicht. Dies mag daran liegen, dass ich gerade in C++ eingestiegen bin und noch überhaupt nichts kann. Dennoch kenne ich mich (sehr) gut in Java aus und dachte, dass es mir etwas einfacher fällt fertige "Projekte" zum laufen zu bringen.

Wie bringt man also diese drei Dateien zum laufen? Ich habe ein neues Projekt erzeugt (Konsolenapplikation), die Dateien gespeichert und unter "Projekt > Add files ..." zum Projekt hinzugefügt. Und dann bin ich auf kompilieren gegangen. Und diese Fehler kamen raus:

CodeBlocks schrieb:
-------------- Build: Debug in Test ---------------

Linking console executable: bin\Debug\Test.exe
obj\Debug\socket.o:C:/Test/Test/socket.cpp:38: undefined reference to `WSAStartup@8'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:46: undefined reference to `WSACleanup@0'
obj\Debug\socket.o: In function `Socket':
C:/Test/Test/socket.cpp:52: undefined reference to `socket@12'
C:/Test/Test/socket.cpp:52: undefined reference to `socket@12'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:96: undefined reference to `closesocket@4'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:105: undefined reference to `ioctlsocket@12'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:113: undefined reference to `recv@16'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:130: undefined reference to `recv@16'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:153: undefined reference to `send@16'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:157: undefined reference to `send@16'
obj\Debug\socket.o: In function `SocketServer':
C:/Test/Test/socket.cpp:166: undefined reference to `htons@4'
C:/Test/Test/socket.cpp:167: undefined reference to `socket@12'
C:/Test/Test/socket.cpp:174: undefined reference to `ioctlsocket@12'
C:/Test/Test/socket.cpp:178: undefined reference to `bind@12'
C:/Test/Test/socket.cpp:179: undefined reference to `closesocket@4'
C:/Test/Test/socket.cpp:183: undefined reference to `listen@8'
C:/Test/Test/socket.cpp:166: undefined reference to `htons@4'
C:/Test/Test/socket.cpp:167: undefined reference to `socket@12'
C:/Test/Test/socket.cpp:174: undefined reference to `ioctlsocket@12'
C:/Test/Test/socket.cpp:178: undefined reference to `bind@12'
C:/Test/Test/socket.cpp:179: undefined reference to `closesocket@4'
C:/Test/Test/socket.cpp:183: undefined reference to `listen@8'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:187: undefined reference to `accept@12'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:189: undefined reference to `WSAGetLastError@0'
obj\Debug\socket.o: In function `SocketClient':
C:/Test/Test/socket.cpp:206: undefined reference to `gethostbyname@4'
C:/Test/Test/socket.cpp:213: undefined reference to `htons@4'
C:/Test/Test/socket.cpp:217: undefined reference to `connect@12'
C:/Test/Test/socket.cpp:218: undefined reference to `WSAGetLastError@0'
C:/Test/Test/socket.cpp:206: undefined reference to `gethostbyname@4'
C:/Test/Test/socket.cpp:213: undefined reference to `htons@4'
C:/Test/Test/socket.cpp:217: undefined reference to `connect@12'
C:/Test/Test/socket.cpp:218: undefined reference to `WSAGetLastError@0'
obj\Debug\socket.o: In function `SocketSelect':
C:/Test/Test/socket.cpp:242: undefined reference to `select@20'
C:/Test/Test/socket.cpp:242: undefined reference to `select@20'
obj\Debug\socket.o:C:/Test/Test/socket.cpp:247: undefined reference to `__WSAFDIsSet@8'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 2 seconds)
35 errors, 0 warnings

Gruß,
tuxIt!
 
hast du mit Ws2_32.lib verlinkt?
Diese lib musste einbinden.

falls unter vs:
im Projektmappen Explorer rechtsklich auf Projektname -> Eigenschaften
Konfigurationseigenschaften -> Linker -> Eingabe
im Feld "zusätzliche Abhängigkeiten" die Lib hinten anhängen

Gruß
soyd
 
Zuletzt bearbeitet:
Leider arbeite ich nicht mit VS (=Visual Studio) sondern mit CodeBlocks. Wo finde ich denn diese "ws2_32.lib"?

Heißt das, dass ich diese Dateien nur unter Windows kompilieren und nutzen kann und nicht auch unter Linux (oder gar Mac OS)? Oder gibt es diese Bibliothek auch für Linux?

Ich habe C++ gewählt, weil ich zwar die Plattformunabhängigkeit von Java gut gebrauchen kann, aber etwas "natives" haben wollte, was keine extra Software benötigt um ausgeführt zu werden.

Gruß,
tuxIt!
 
tuxIt! schrieb:
Leider arbeite ich nicht mit VS (=Visual Studio) sondern mit CodeBlocks. Wo finde ich denn diese "ws2_32.lib"?

VS ist kostenlos, zumindest die Express.

http://www.microsoft.com/germany/express/

tuxIt! schrieb:
Heißt das, dass ich diese Dateien nur unter Windows kompilieren und nutzen kann und nicht auch unter Linux (oder gar Mac OS)? Oder gibt es diese Bibliothek auch für Linux?

Schau mal in die Überschrift auf der von dir verlinkten Seite. Da steht ganz oben dick und fett.

C++ Socket Class for Windows

Zu erkennen auch an der Header #include <WinSock2.h>

tuxIt! schrieb:
Ich habe C++ gewählt, weil ich zwar die Plattformunabhängigkeit von Java gut gebrauchen kann, aber etwas "natives" haben wollte, was keine extra Software benötigt um ausgeführt zu werden.

Sockets, also Netzwerkschnittstellen sind OS-spezifisch! C++ unterstützt keine plattformunabhängige Netzwerkprogrammierung ohne den Einsatz von externen Abstraktionsschichten, wie Frameworks (Qt, etc.) oder Bibliotheken (boost::asio).
 
Wo finde ich denn diese "ws2_32.lib"?

Die solltest du in der Plattform SDK finden, muss extra installiert werden...
hier für win7:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b

für multiplattform würd ich ne eigene Abstraktionsklasse schreiben...
mit switches ob nun für unix oder win compiliert wird...
So haste einen Programmcode für beide Os, und eine Abstraktionschicht für die os-spezifischen socks Klassen. Wie schon Stefan gemeint hat.

irgendwo hab ich sowas noch rumliegen, Rechnernetze 1 sei Dank :)

gruß
 
Also, ich bin jetzt auf C gekommen und habe das Beispiel von Gallileo "C von A bis Z" (hier) in eine Datei gepackt und wieder in Code::Blocks. Das hat wieder nicht funktioniert. Aber, wenn ich es unter Linux in den GCC packe ("gcc -out echo-server server.c"), dann kompiliert er das ohne meckern! Was mache ich unter Wwindows falsch?

Gruß,
tuxIt!

Code:
/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <time.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>
#include <arpa/inet.h>
#include <unistd.h>
#endif

/* Portnummer */
#define PORT 1234

/* Puffer für eingehende Nachrichten */
#define RCVBUFSIZE 1024

#ifdef _WIN32
   static void echo(SOCKET);
#else
   static void echo( int );
#endif

static void error_exit(char *errorMessage);

/* Die Funktion gibt Daten vom Client auf stdout aus,
 * die dieser mit der Kommandozeile übergibt. */
#ifdef _WIN32
static void echo(SOCKET client_socket)
#else
static void echo(int client_socket)
#endif
{
    char echo_buffer[RCVBUFSIZE];
    int recv_size;
    time_t zeit;

    if((recv_size =
            recv(client_socket, echo_buffer, RCVBUFSIZE,0)) < 0)
        error_exit("Fehler bei recv()");
    echo_buffer[recv_size] = '\0';
    time(&zeit);
    printf("Nachrichten vom Client : %s \t%s",
            echo_buffer, ctime(&zeit));
}

/* Die Funktion gibt den aufgetretenen Fehler aus und
 * beendet die Anwendung. */
static void error_exit(char *error_message) {

#ifdef _WIN32
    fprintf(stderr,"%s: %d\n", error_message, WSAGetLastError());
#else
    fprintf(stderr, "%s: %s\n", error_message, strerror(errno));
#endif

    exit(EXIT_FAILURE);
}

int main( int argc, char *argv[]) {
    struct sockaddr_in server, client;

#ifdef _WIN32
    SOCKET sock, fd;
#else
    int sock, fd;
#endif

    unsigned int len;

#ifdef _WIN32
    /* Initialisiere TCP für Windows ("winsock"). */
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD (1, 1);
    if (WSAStartup (wVersionRequested, &wsaData) != 0)
        error_exit( "Fehler beim Initialisieren von Winsock");
    else
        printf("Winsock initialisiert\n");
#endif

    /* Erzeuge das Socket. */
    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0)
        error_exit("Fehler beim Anlegen eines Sockets");

    /* Erzeuge die Socketadresse des Servers. */
    memset( &server, 0, sizeof (server));
    /* IPv4-Verbindung */
    server.sin_family = AF_INET;
    /* INADDR_ANY: jede IP-Adresse annehmen */
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    /* Portnummer */
    server.sin_port = htons(PORT);

    /* Erzeuge die Bindung an die Serveradresse
     * (genauer: an einen bestimmten Port). */
    if(bind(sock,(struct sockaddr*)&server, sizeof( server)) < 0)
        error_exit("Kann das Socket nicht \"binden\"");

    /* Teile dem Socket mit, dass Verbindungswünsche
     * von Clients entgegengenommen werden. */
    if(listen(sock, 5) == -1 )
         error_exit("Fehler bei listen");

    printf("Server bereit - wartet auf Anfragen ...\n");
    /* Bearbeite die Verbindungswünsche von Clients
     * in einer Endlosschleife.
     * Der Aufruf von accept() blockiert so lange,
     * bis ein Client Verbindung aufnimmt. */
    for (;;) {
        len = sizeof(client);
        fd = accept(sock, (struct sockaddr*)&client, &len);
        if (fd < 0)
            error_exit("Fehler bei accept");
        printf("Bearbeite den Client mit der Adresse: %s\n",
           inet_ntoa(client.sin_addr));
        /* Daten vom Client auf dem Bildschirm ausgeben */
        echo( fd );

        /* Schließe die Verbindung. */
#ifdef _WIN32
        closesocket(fd);
#else
        close(fd);
#endif
    }
    return EXIT_SUCCESS;
}
 
ist das gleiche wie oben du musst die LIB einbinden!!!!
eventuell noch <windows.h> in die includes...
steht aber alles schön da beschrieben.

Mit CodeBlocks kenn ich mich nicht aus, aber irgendwo kannste da auch Libs einbinden...
ohne die Plattform SDK die ich oben erwähnt hab wirst aber nicht weit kommen ;)

mal ganz einfach gesagt:
winsock.h benutzt Funktionen aus der ws2_32.lib deshalb musst du sie verlinken, wird statisch während dem compilen verlinkt...
unix: socks.h enthält alles was du brauchst kein Linken nötig

*edit
http://www.codeblocks.org/docs/manual_de.pdf
ab Seite 42 wird beschrieben wie du Libs einbindest ;)

würde aber vorschlagen schau die mal den Unterschied zwischen .h, .c , .lib, .dll an, was macht import was ist der Linker ;) ist hilfreich für die Zukunft

gruß
 
Zuletzt bearbeitet:
Zurück
Oben