client IP auslesen
-
Hi,
ich schreibe momentan zwei kleine Programme, eine Client Anwendung und eine Server Anwendung. Bisher tut mein Programm folgendes:
- Server Anwendung öffnet einen Socket und hört ihn ab.
- Client Anwendung verbindet sich und übermittelt Kommandos.
- Server handelt je nach KommandoNun öffnet der Client selbst einen Socket und soll einen Datenstrom vom Server empfangen. Um sich mit dem Client verbinden zu können, braucht der Server natürlich die IP. Diese hat er ja durch die bestehende Verbindung bereits.
Meine Frage: wie lese ich diese aus?
Angehängt, der relevante Teil meiner Server Anwendung. Aus diesen Informationen will ich die Client Adresse auslesen.Um Fragen vorweg zu nehmen, warum ich noch eine Verbindung aufbaue wo doch bereits eine bidirketionale Verbindung besteht... Es soll eine reine "Kommando" Verbindung und eine reine Daten-Verbindung geben
int main(int argc, char *argv[]) { pthread_t data; //define thread for data transmission int sockfd, newsockfd; //both are file descriptors for open sockets int p=1; //p indicates if data transmission thread already in use (p=0) int n; //file descriptor for sockets socklen_t clilen; //Clientadresse length char command[255]; //Buffer for client input struct sockaddr_in serv_addr, cli_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); //socket() creates endpoint, returns descriptor //AF_INET = IPv4 //SOCK_STREAM = seq., rel., two-way, connection-based byte streams. if (sockfd < 0) { error("ERROR opening socket"); } bzero((char *) &serv_addr, sizeof(serv_addr)); //initialisiert serv_addr mit 0 serv_addr.sin_family = AF_INET; //use IPv4 serv_addr.sin_addr.s_addr = INADDR_ANY; //IP-address of the host serv_addr.sin_port = htons(2556); //define portnumber //bind() assigns the address specified by addr to the socket referred to by the file descriptor sockfd. //int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { error("ERROR on binding"); } while (1) { bzero(command,255); //initialisiere command buffer listen(sockfd, 5); //int listen(int socket, int backlog) - backlog, something with the queue clilen = sizeof(cli_addr); //Länge der client addresse newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); read(newsockfd,command,255); if (n < 0) error("ERROR reading from socket"); ***more Code*** } close(sockfd); return 0; }
Viel Text für eine kurze Frage, ich hoffe ich konnte mein Problem deutlich machen und jemand hat eine Lösung für mich.
Viele Grüße,
Pingu
-
Du hast da eine Variable namens cli_addr...
-
Ist mir bekannt, bloß wie les ich da die IP aus? Hab schon mit inet_ntoa() und konsorten rumgespielt aber nichts brauchbares rausbekommen.
Ich brauche die Adresse wenn möglich als String
-
inet_ntoa klingt schon nicht verkehrt. Wenn du jetzt noch etwas genauer werden könntest als
P!ngu schrieb:
rumgespielt aber nichts brauchbares rausbekommen
könnte man dir sogar weiterhelfen.
-
In der FAQ ist etwas (vielleicht) brauchbares:
-
Hi,
@MFK
rumgespielt meint "try and error". Habe einfach alles mögliche (cli_addr. ...) in inet_ntoa() geworfen und geschaut was dabei rauskommt. Allerdings gabs entweder Fehler oder es wurde ein "int" zurückgegeben.
Ich hab natürlich bereits geschaut wie die Strukturen aussehen, aus denen ich da die Information ziehen möchte.Allerdings blick ich da nicht ganz durch, in der Struktur gibts dann ne Struktur, mit nem Zeiger auf n Array von Zeigern und noch mehr Strukturen...@gigg
danke für den Hinweisder für mich relevante Teil ist wohl folgender...
struct sockaddr_in *i; ... i = (struct sockaddr_in*)&ifa.ifr_addr; puts (inet_ntoa(i->sin_addr));
allerdings hilft mir das nicht weiter, da bei mir ja folgende Situation vorliegt...
struct sockaddr_in serv_addr, cli_addr;
Vermutlich gibts da ne ganz einfache Lösung, aber ich bin relativ neu in C und insbesondere Zeigern und Strukturen.
-
Hallo,
puts (inet_ntoa(cli_addr.sin_addr));
MfG,
Probe-Nutzer
-
puts (inet_ntoa(serv_addr.sin_addr)); puts (inet_ntoa(cli_addr.sin_addr));
foo->bar ist kurz für *(foo).bar
-
@Probe-Nutzer, Insider
naja soviel das foo->bar = (*foo).bar ist weiß ich dann doch.
leider ist mein cli_addr aber kein Zeiger, sondern nur eine Variable, weshalb
puts (inet_ntoa(cli_addr.sin_addr));
nicht funktioniert.
gcc sagt dazu folgendes...
$ gcc ./open_socket.c -lpthread -o ./open_socket ./open_socket.c: In Funktion »main«: ./open_socket.c:84:1: Warnung: Übergabe des Arguments 1 von »puts« erzeugt Zeiger von Ganzzahl ohne Typkonvertierung [standardmäßig aktiviert] /usr/include/stdio.h:692:12: Anmerkung: »const char *« erwartet, aber Argument hat Typ »int«
-
Der Fehler, den gcc ausgibt, hat überhaupt nichts damit zu tun, dass cli_addr kein Zeiger ist. Zeige besser die Zeile 84, damit klar ist, was das Problem ist. Dort verwendest du offensichtlich nicht inet_ntoa (denn das gibt keine Ganzzahl zurück, wie gcc feststellt), sondern...?
MfG,
Probe-Nutzer
-
Zeile 84 ist
puts (inet_ntoa(cli_addr.sin_addr));
dachte das wäre aus meinem Post ersichtlich.
-
Ok, dann noch einmal ganz genau, warum ich anzweifeln musste, dass das die richtige Zeile ist (dein main oben hat z.B. auch nur 54 Zeilen) : die angegebene Zeile kann die Warnung (nicht Fehler, wie ich oben schrieb) nicht verursachen, weil inet_ntoa, wie nachzulesen ist, char* zurück gibt, und keine Ganzzahl, nicht die Übergabe von cli_addr.sin_addr an inet_ntoa ist das Problem, sondern das puts einen int bekommt, den inet_ntoa nicht als Ergebnis liefern kann. Hast du irgendwo noch etwas mit inet_ntoa stehen, hast du über main noch etwas, was das verursachen könnte?
MfG,
Probe-Nutzer
-
woanders im Programm wird weder inet_ntoa() noch puts benutzt, lediglich zum testen an folgender Stelle (für gesamten Codeausschnitt siehe Eröffnungspost)
... while (1) { bzero(command,255); //initialisiere command buffer listen(sockfd, 5); //int listen(int socket, int backlog) - backlog, something with the queue clilen = sizeof(cli_addr); //Länge der client addresse newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); -----> puts (inet_ntoa(cli_addr.sin_addr)); read(newsockfd,command,255); ...
-
Include vergessen?
-
sähe da die Meldung von gcc nicht anders aus?
hier die includes...#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h>
-
P!ngu schrieb:
sähe da die Meldung von gcc nicht anders aus?
Ich bin nicht so der C-Fachmann, aber war das im alten Standard nicht so, dass undeklarierte Funktionen als Rückgabetyp int angenommen werden? Das würde zur Fehlermeldung passen
P!ngu schrieb:
hier die includes...
man inet_ntoa erwähnt noch
#include <arpa/inet.h>
-
damit funktionierts!
Vielen Dank MFK
hier nochmal kurz die Zusammenfassung...
Situation: Client hat sich bereits mit Server verbunden.
Frage: Wie bekomme ich auf Serverseite die IP vom Client als String?
Antwort: so...... #include <arpa/inet.h> ... int main(int argc, char *argv[]) { ... struct sockaddr_in serv_addr, cli_addr; ... while (1) { ... listen(sockfd, 5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); puts (inet_ntoa(cli_addr.sin_addr)); ...
Vielen Dank auch an alle anderen die mir hier geholfen haben.
Schönes Wochenende,
Pingu