ubuntuusers.de

TCP Echo Server + Client in C

Status: Gelöst | Ubuntu-Version: Ubuntu 8.10 (Intrepid Ibex)
Antworten |

Njutik

Anmeldungsdatum:
29. Januar 2009

Beiträge: 52

Hallo Leute!

Ich bin absolut neu sowohl was Linux generell angeht als auch, was die Programmierung von TCP Socket angeht. Da sich das Thema meiner Studienarbeit sich darum dreht, bin ich gerade dabei mich einzuarbeiten. Seit gestern versuche ich, eine TCP Echo Server + Client Anwendung zu implementieren. Die Quelltexte, die ich in Anhang getan habe, stammen aus dem Buch "TCP/IP Sockets in C". Ich habe jede Quelldatei in einem separaten Terminal compiliert und gelinkt. Der Compiler hat bei keiner Datei einen Fehler gemeldet. Achso, das Ziel soll follgendes sein: der Client soll eine Verbindung zu einem Server aufbauen und dem Server einen String schicken. Der Server soll das, was er vom Client empfangen hat einfach wieder zurück schicken. Als Server gebe ich den localhost (also 127.0.0.1) an und verwende den Port Nummer 7. Da der Server ewig läuft, starte ich den Server auf einem Terminal mit ./tcpserver 7 127.0.0.1. Darauf erhalte ich folgende Meldung: Socket created! bind() successfull listen() successfull Danach kommt auf dem Terminal keine Angabe mehr und bei den Prozessen in der Systemsteuerung steht, das tcpserver-Prozess schläft und auf den connect() wartet. Dann scheint es zumindest hier zu funktionieren. Auf dem Terminal erscheint nun gar nichts neues mehr, sondern ein kleines schwarzes Rechteck blinkt in der linken unteren Ecke.

So, auf einem anderen separaten Terminal starte ich den Client mit ./tcpclient 127.0.0.1 "Echo this" 7. Darauf erhalte ich: Socket created! int sock = 3 connect() successfull int con = 0 the length of the string to echo: 10 Danach erscheint einfach die ganz normale Zeile im Terminal (anna@anna-desktop:~$). Also meldet das Programm keinen Fehler, aber zum Senden kommt es offenbar auch nicht. Kann mir da jemand helfen? Woran liegt das? Ich habe versucht, den localhost anzupingen. Geht wunderbar. Wäre Klasse, wenn jemand weiterwüsste.

liebe Grüße

Anna

tcpserver.c (3.7 KiB)
Download tcpserver.c
tcpclient.c (3.7 KiB)
Download tcpclient.c

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4673

Wohnort: Berlin

@Njutik: Ohne jetzt in den Quelltext geschaut zu haben; Startest Du den Server auch mit root-Rechten? An Ports unter 1024 dürfen sich Server von normalen Benutzern nämlich sonst nicht binden. Ist eine Sicherheitsmassnahme, damit normale Benutzer nicht so tun können als seien sie zum Beispiel der "offizielle" Webserver auf Port 80, oder vielleicht sogar ein SSH-Daemon.

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Wenn du dir deinen Server einmal kompilierst und dann "netstat -tulpen" eingibst dann wirst du sehen das dein Server anscheind "random" immer auf einen anderen Port horcht. Er horcht nichtmal auf die IP Addresse 127.0.0.1 sondern auf 0.0.0.0 und ist somit auch von ausserhalb deines Rechners erreichbar.

Aber verbinden und die Funktionalität eines echo servers erfüllt es. Das habe ich aber mit telnet und nicht mit deinem geschriebenen Client getestet.

Der Compiler hat bei keiner Datei einen Fehler gemeldet.

Wenn du mit der Option "-Wall" deinen Server compilierst dann gibt es ein Warning das die Variable "i" ungenutzt ist.

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

Auszug aus deinem Code:

1
2
3
4
5
/*Construct local adress structure*/
echoServAddr.sin_family = AF_INET;	/*Internet adress family*/
echoServAddr.sin_addr.s_addr = inet_addr(servIPAddr); 	/*any incoming interface*/
echoServAddr.sin_port = htons(echoServPort);	/*Echo Server Port*/
memset(&echoServAddr, 0, sizeof(echoServAddr));

Sowohl in tcpclient als auch in tcpserver gibtst du dir viel Mühe, die Adresstrukturen mit Daten zu füllen, um danach per memset alles wieder mit 0 zu überbügeln. Damit lauscht dein Server auf Zufallsport an 0.0.0.0.

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Ohne die "memset" Zeile die radeo bemängelt funktioniert es, nur noch nen kleiner Flüchtigkeistfehler. Die Programm Argumente sind "<port> <server>" wenn du dein Server ohne Argumente aufrufst steht dort eine umgekehrte reihenfolge. "<server> <port>". Ansonsten beendet sich das Programm dann mit einem "Segmentation Fault".

<server> <port> ist übrigens besser. da man so <port> weg lassen könnte und du es in deiner App auf default "7" stellen könntest. <server> könntest du auch optional lassen und würde ich default auch "127.0.0.1" machen.

Njutik

(Themenstarter)

Anmeldungsdatum:
29. Januar 2009

Beiträge: 52

Liebe Leute, alle die mir geantwortet haben!

Vielen vielen Dank für Eure Hilfe! Es lag tatsächlich daran, dass ich die komplette sockaddr_in Struktur des Servers zunächst mit Werten gefüllt und dann gelöscht habe. Ich habe diesen memset() - Befehl an den Anfang gestellt - einfach um sicherzustellen, dass die Struktur sockaddr_in des Servers leer ist und - oh Wunder! es läuft. Nochmals vielen vielen Dank, Leute, dass Ihr Euch Zeit für mein Problem genommen habt und mir geantwortet habt. Ihr habt mir damit wirklich sehr geholfen.

liebe Grüße

Anna

Hauke82

Anmeldungsdatum:
12. Februar 2009

Beiträge: 4

Hallo liebe User,

ich habe noch ein Verständnissproblem, wie wird man merken das der Client mit dem Socket verbunden ist,Meldung? und was kann ich dann damit anfangen? Kann ich das ganze auch über Crosskabel oder W-lankarten mit 2Rechnern anstellen, und dann einen Befehl auf dem Client bzw. Serverrechner ausführen, wie zB "Hallo" auf dem Terminal des Servers ausgeben? Müsste ich dazu nicht die IP der Karte angeben, oder wieso kann man einfach 127.0.0.1 den localhost benutzen? Das ist doch dann keine direkte Verbindung zu einem Server..? vg Hauke

Der vollständigkeithalber, hier noch ein Beitrag den ich in einem anderen Forum gepostet habe, ich würde mich über die Antworten freuen! http://www.pc-forum24.de/sonstiges-server/10404-zwei-rechner-ueber-socket-verbinden.html

odr vielleicht die Frage an Njutik, da es bei dir so gut geklappt hat könntest du nochmal die Ausgabe des Clients posten und was die Sachen dann genau meinen? Oder vill auch nochmal den korrigierten Quelltext? danke schonmal!

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Hauke82 schrieb:

ich habe noch ein Verständnissproblem, wie wird man merken das der Client mit dem Socket verbunden ist,Meldung?

Zu ungenau. Im welchem Kontext redest du und "wer" wird was Mercken? Ein Benutzer/admin der vor dem PC sitzt? Der Server? Der Client?

Kann ich das ganze auch über Crosskabel oder W-lankarten mit 2Rechnern anstellen, und dann einen Befehl auf dem Client bzw. Serverrechner ausführen, wie zB "Hallo" auf dem Terminal des Servers ausgeben?

Die verwendete Hardware spielt hier gar keine Rolle. Darum kümmert sich das Betriebssystem nicht du als Programmierer. Ob eine Netzwerkverbdinung über WLAN, LAN, oder welchen Adapter auch immer herstellst spielt hier keine Rolle.

Müsste ich dazu nicht die IP der Karte angeben,

Von welcher karte? Und wenn du was tuen möchtest?

oder wieso kann man einfach 127.0.0.1 den localhost benutzen?

127.0.0.1 ist eine spezielle IP Addresse die immer dein aktueller Rechner ist. "localhost" ist ein symbolischer name dafür. Allerdiengs ist das ganze Class A Netz 127 localhost.

Das ist doch dann keine direkte Verbindung zu einem Server..?

hmm, eine verbindung ist eine verbindung, was ist eine "direkte" oder eine "undirekte" in deinen Augen? Ob nun Client/Server auf den selben rechner laufen oder unterschiedlichen spielt da keine rolle.

Hauke82

Anmeldungsdatum:
12. Februar 2009

Beiträge: 4

Okay, ich habe jetzt wie beschrieben den "Echo Server" mal nur auf einem Rechner laufen lassen, und verstanden, dass Client und Server sich im Falle der Verwendung von localhost auf ein und demselben Rechner befinden. Das hat auch einwandfrei funktioniert.

Was jetzt für mich noch interessant ist, dass ich den "Echo Server" auf einem Rechner im Netzwerk aktiviere, um dann von einem Zweiten Rechner, den ersten anzusprechen und das Echo zu bekommen. Ich bin gerade am probieren und melde mich wieder, im Moment kann ich leider die Recher per WLAN nicht pingen, obwohl sie sich im selben AD-hoc Netzwerk befinden, ich werde das ganze gleich aber mal mit Crosskabel probieren.

danke Sid

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Hauke82 schrieb:

Was jetzt für mich noch interessant ist, dass ich den "Echo Server" auf einem Rechner im Netzwerk aktiviere, um dann von einem Zweiten Rechner, den ersten anzusprechen und das Echo zu bekommen.

Wenn du den Echo Server auf einem Rechner laufen lässt und du möchtest das sich andere Clients zu diesem verbinden können, dann musst der Server Allerdiengs auf die IP Adresse "0.0.0.0" lauschen. Sonst ist er nicht von aussen erreichbar.

Welche Programme auf welchen TCP oder UDP Ports laufen kannst du mit "netstat -tulpen" herausfinden.

Hauke82

Anmeldungsdatum:
12. Februar 2009

Beiträge: 4

Ja sehr gut. Mit telnet <IP> <PORT>; kann ich zu dem TCPServer verbinden. Und mit dem anderen Client hab ich jetzt auch kapiert wie es funktioniert: ./tcpclient 192.168.X.X "Hallo" <PORT>

Das ist schonmal sehr gut, Übers Wochenende bin ich leider nicht hier. Viele Grüße! Als nächstes werd ich dann einen timestamp einbauen oder die Rechner synchronisieren, mal schaun ☺

Antworten |