PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Simples Server programm lässt sich nicht an Port binden



buffoon
16-09-2007, 20:47
Hi!

Ich bin gerade dabei mich ein bisschen in die sockets einzuarbeiten. Ich gehe nach folgendem tutorial vor:
http://www.pronix.de/pronix-278.html

Der Unterschied hierzu ist, dass ich das alles in c++ machen will, da ich das dann in Klassen rein hauen kann welche ich später in einem anderen Programm verwenden werde, aber das dürfte wohl nicht so das Problem sein...

Das Programm will sich jetzt nicht an einen Port binden. Ich bekomme immer die Ausgabe:


buffoon@buffoon:~/cpp/netzwerk$ ./server
Socket wurde angelegt
Der Port ist nicht frei
Nachricht zum Versenden


und das Programm sieht so aus:

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define BUF 1024

using namespace std;

int main()
{
int create_socket ,new_socket;
socklen_t addrlen;

char *buffer = (char *) malloc(BUF);
ssize_t size;
struct sockaddr_in address;
const int y = 1;

if(create_socket = socket (AF_INET, SOCK_STREAM, 0) > 0)
cout << "Socket wurde angelegt" << endl;
else
{
cout << "Socket konnte nicht angelegt werden" << endl;
exit(1);
}

setsockopt( create_socket, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(15000);

if(bind(create_socket, (struct sockaddr *) &address, sizeof (address)) !
= 0)
{
cout << "Der Port ist nicht frei" << endl;
}
listen (create_socket, 5);

addrlen = sizeof(sockaddr_in);

while (1)
{
new_socket = accept (create_socket, (struct sockaddr *) &address
, &addrlen);
if(new_socket > 0)
cout << "Ein Client (" << inet_ntoa(address.sin_addr) <<
") ist verbunden" << endl;

do
{
cout << "Nachricht zum Versenden" << endl;

fgets(buffer, BUF, stdin);
send(new_socket, buffer, strlen (buffer), 0);
size = recv(new_socket, buffer, strlen(buffer), 0);
if (size > 0)
buffer[size] = '\0';
cout << "Nachricht empfangen: " << buffer << endl;
} while (strcmp (buffer, "quit\n") != 0);
close (new_socket);
}
close (create_socket);
exit (0);
}

jeebee
16-09-2007, 20:52
[...]
edit: original gelöscht, hab den code nicht richtig gelesen.

Also bei mir funktionierts, g++ -Wall findet nur, dass man um die Anweisung in der if-Abfrage auf Zeile 22 (create_socket = socket (...)) noch Klammern machen sollte. also
if((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0) anstelle von deiner Version. Wenn ich das mache, funktioniert die ganze Sache auch (wieso: keine Ahnung lt. gdb ist create_socket = 1 (ohne zus. Klammern) und create_socket=5 (mit zus. Klammern))

buffoon
16-09-2007, 21:11
Komisch, aber sollte nicht

if(bind(...) != 0)
das gleiche sein wie

if(!bind(...))
Auf jedem fall kommt da jetzt keine Fehlermeldung mehr. Danke

Jetzt habe ich aber das Problem, dass sich der Client nicht verbinden kann und ich wüßte wirklich nicht wo ich nach einem Grund suchen könnte. Ich füge mal den Code des Clients ein:

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF 1024

using namespace std;

int main()
{
char *buffer = (char*) malloc (BUF);
int size;

// Anlegen eines Sockets
int create_socket;
if (create_socket = socket (AF_INET, SOCK_STREAM, 0) > 0)
cout << "Socket wurde angelegt" << endl;
else
{
cout << "Socket konnte nicht angelegt werden" << endl;
exit(1);
}

// Begin zum Aufbau einer Verbindung
struct sockaddr_in address;

address.sin_family = AF_INET;
address.sin_port = htons (15000);
inet_aton ("127.0.0.1", &address.sin_addr);

if (connect ( create_socket, (struct sockaddr *) &address, sizeof (address) ) == 0)
cout << "Verbindung erfolgreich hergestellt" << endl;
else
{
cout << "Verbindung nicht erfolgreich hergestellt" << endl;
exit(1);
}

do {
size = recv(create_socket, buffer, BUF-1, 0);
if( size > 0)
buffer[size] = '\0';
cout << "Nachricht erhalten: " << buffer << endl;
if (strcmp (buffer, "quit\n"))
{
cout << "Nachricht zum Versenden: ";
fgets (buffer, BUF, stdin);
send(create_socket, buffer, strlen (buffer), 0);
}
} while (strcmp (buffer, "quit\n") != 0);

close (create_socket);
}

jeebee
16-09-2007, 21:16
Hmm, du hast wohl mein edit nicht mehr gesehen. Der Fehler liegt in den Zeilen server.cpp:22 und client.cpp:18 wo jeweils Klammern um die Zuweisung im if fehlen (auf der von dir angegebenen Seite stehen diese Klammern auch!). Warum genau dass etwas anderes gemacht wird, weiss ich nicht, aber die Variable socket_create enthält jedenfalls andere Werte mit/ohne Klammern (vgl. oberer Post)

MfG und sorry für die Verwirrung ;)

PS: Ah ja, gewöhn dir an, beim Kompilieren den Schalter -Wall anzugeben (alle Warnungen), dann erhältst du Hinweise zu solchen Problemen.

buffoon
16-09-2007, 21:26
Oh ja, hab den edit nicht mehr gesehen... Jetzt scheint es aber zu funktionieren. Da wäre ich wohl ohne deine Hilfe nicht drauf gekommen...

Dankeschön für die Hilfe
grüße buffoon

jeebee
16-09-2007, 21:28
Kein Problem, und wie gesagt, mit
g++ -Wall -o prog prog.cpp findest du schon recht viele solche Dinge.

buffoon
16-09-2007, 21:34
Und jetzt fällt mir auch auf warum:

Ohne die Klammern wird nämlich der Ausdruck rechts neben dem = ausgewertet und dann rein geschrieben. Dadurch dass die Klammern fehlen kommt das "> 0" auch zu diesem ausdruck dazu und das kann dann natürlich nur ein boolean wert sein, also 0 oder 1.
Wenn ich jetzt die Klammern setze wird das zeug zuerst in die Variable geschrieben und anschließend erst die Anweisung überprüft.

grüße buffoon

jeebee
16-09-2007, 21:43
ach stimmt, ich kann die Präzedenz-Regeln auch nicht und mache solche Dinge meist nach dem Motto "lieber zuviel Klammern als zuwenig" :)

Gruss jeebee