[C] Socket für TCP/UDP Übertragung programmieren

AW: [C] Socket für TCP/UDP Übertragung programmieren

Du musst deine Variablen am Anfang der Funktion deklarieren, mittendrin geht bei klassischem C nicht. Da du die Variablen im laufenden Code deklarierst, kann es sein, dass er die deshalb nicht findet.
Nein, das hat auch nichts gebracht. Außerdem müsste er dann auch bei anderen Variablen Fehlermeldungen bringen, nicht nur bei diesem struct socklen_t len. Dann dürfte ihm z.B. das int len ein Bisschen weiter unten auch nicht recht sein ...

Und das mit dem sin_size habe ich auch noch nicht weggebracht.

[EDIT]
Bin schon am Überlegen, ob ich den Teil, also diese 3 Zeilen, die einen zugewiesenen Port ermitteln sollen, überhaupt brauche ...
Code:
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    struct socklen_t len;
    getsockname(sockfd, (struct sockaddr *)&my_addr, &len);
    printf("Port: %d\n", ntohs(my_addr.sin_port));
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Nein, das hat auch nichts gebracht. Außerdem müsste er dann auch bei anderen Variablen Fehlermeldungen bringen, nicht nur bei diesem struct socklen_t len. Dann dürfte ihm z.B. das int len ein Bisschen weiter unten auch nicht recht sein ...
Nicht wenn der Compiler vorher abbricht. War ein Versuch wert ^^

Ich habe das mal eben auf meiner Linux Box ausprobiert:
Code:
#include <stdio.h>
#include <errno.h>
#include <string[B].h[/B]>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_server(int port) {
    /* socket() - Socket anfordern */
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    /* bind() - Den eigenen Port festlegen */
    struct sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(port);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind()");
    }
    /* Zugewiesenen Port ermitteln: */
    [STRIKE]struct[/STRIKE] socklen_t len; [B]/* das ist kein struct */[/B]
    getsockname(sockfd, (struct sockaddr *)&my_addr, &len);
    printf("Port: %d\n", ntohs(my_addr.sin_port));

    /* listen() - Auf eingehende Verbindungen warten */
    if (listen(sockfd, 5) == -1) {
        perror("listen()");
    }

    /* accept() - Die eingehende Verbindung annehmen */
    [STRIKE]struct[/STRIKE] socklen_t sin_size = sizeof(struct sockaddr_in); [B]/* siehe oben */[/B]
    struct sockaddr_in remote_host;
    int sock2 = accept(sockfd, (struct sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

    /* send() und recv() - Senden und Empfangen mit TCP */
    char *msg = "Testmessage.\n";
    int len[B]2[/B] = strlen(msg); [B]/* du hast schon eine Variable mit dem Namen len */[/B]
    if (send(sock2, msg, len[B]2[/B], 0) == -1) {
        perror("send()");
    }
    char buf[1024];
    if (recv (sock2, buf, 1024, 0) == -1) {
        perror("recv()");
    }
    int x=0;
    while (x!=1024) {
        printf("%c", buf[x]);
        x++;
    }

    /* close() - Socket freigeben */
    [STRIKE]int close(int fd);[/STRIKE]
[B]     close(sockfd);[/B]
}

/* Parameter: UDP/TCP, Client, Textnachricht, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */
int main(int argc, char *argv[]) { 
    int port;

    if (argv[1]=="TCP" && argv[2]=="Server") {
        port = *argv[3]; [B]/*nee, guck dir mal atoi() an. Hier weist du den int-Wert des ersten Characters als Port zu */[/B]
        tcp_server(port);
    } 

    return 0;
}
bei mir kompiliert das (GCC 4.7.2)
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ok, nur wo nehme ich die Nachricht für msg her? Ich programmiere ja jetzt erstmal den Server und der weiß ja nicht, was ihm der Client schicken wird?! Irgendwas anderes muss auf jeden Fall statt "Testmessage.\n" hin, nur habe ich noch nicht ganz durchschaut, was. Die Textnachricht vom Client muss irgendwie in char *msg rein ...

Du kannst ja eine Anmeldebestätigung in Form einer Textnachricht an den Client schicken. Bsp. Client 127.0.0.1 hat sich Erfolgreich beim Server angemeldet. Oder du machst gar keine Ausgabe bei Server und wartest erst mal auf eine Nachricht des Clients und antwortest dann darauf.

Lg.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

@ bingo88
Ok, danke, bis auf ein warning, das wir ignorieren können, kompiliert das jetzt auch bei mir. Ich überlege mir das jetzt mit atoi(), damit auch tatsächlich der als Parameter an main übergebene Port an die Funktion übergeben wird.

@ -Phoenix-
Ich kann mir das alles nicht so einfach aussuchen. Die Aufgabenstellung gibt da ja einiges vor. Vielleicht habe ich aber auch den zweiten Punkt der Aufgabe a falsch verstanden?! Ich dachte, eine übertragene Nachricht, die IPv4-Adresse des Clients und der Port des Clients sollen ausgegeben werden?! An ersterem arbeite ich gerade ... das mit der Adresse und dem Port überlege ich mir dann ...
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

@ bingo88
Ok, danke, bis auf ein warning, das wir ignorieren können, kompiliert das jetzt auch bei mir. Ich überlege mir das jetzt mit atoi(), damit auch tatsächlich der als Parameter an main übergebene Port an die Funktion übergeben wird.
Schön :)
Komischerweise waren die später deklarierten Variablen auch kein Problem, vor einem halben Jahr oder so ging das noch nicht bei meiner Maschine. Allerdings hatte ich da auch eine ältere GCC Version installiert. Auf dem Cluster den wir für einen Kurs nutzen geht es definitiv nicht, allerdings weiß ich nicht, welche Version die da drauf haben. Tendenziell wird die was älter sein :ugly:
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Dann brauchst ja im Server eingentlich nur ein recv, du sollst ja laut Aufgabenstellung vom Server aus nur Daten Empfangen und keine Senden. Die Daten bekommst du über recv, Ip+Port über return by reference von accept.

Lg.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

hast du auch die entsprechenden header für size_t includiert?

Soweit ich das sehe, hast du die stddef.h nicht includiert. Die und die stdio.h sollte man eigentlich immer includieren.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

hast du auch die entsprechenden header für size_t includiert?

Soweit ich das sehe, hast du die stddef.h nicht includiert. Die und die stdio.h sollte man eigentlich immer includieren.
Wir haben das Problem gelöst. struct size_t bla gibt es nich, das struct musste da weg. Hatte ich jetzt auch erst beim selber kompilieren gesehen :D
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Oh, das hatte ich jetzt gar nicht gesehen, dass da ein struct dabei stand :D
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Dann brauchst ja im Server eingentlich nur ein recv, du sollst ja laut Aufgabenstellung vom Server aus nur Daten Empfangen und keine Senden. Die Daten bekommst du über recv, Ip+Port über return by reference von accept.

Lg.
Hm, ja ich hab's mir eh schon gedacht, dass ich das msg Zeugs, also den send() Teil, nicht brauche. Die Schleife für die Ausgabe des Buffer-Inhalts müsste schon stimmen:
Code:
[COLOR=seagreen]/* recv() - Senden und Empfangen mit TCP */    char buf[1024];
    if (recv (sock2, buf, 1024, 0) == -1) {
        perror("recv()");
    }
    int x=0;
    while (x!=1024) {
        printf("%c", buf[x]);
        x++;
    }
Jetzt muss ich mir nur noch das mit der IP-Adresse und dem Port überlegen. Für die IP hätte ich das hier gefunden, aber es passt natürlich nicht 1:1 für mein Beispiel. Zumindest das printf sollte ich übernehmen können:
Code:
int i=0;
    while (hptr->h_addr_list[i]) {
          addr.s_addr = *((long*)hptr->h_addr_list[i++]);
          printf ("IPv4 address: %s\n", inet_ntoa(addr));
    }
Und den Port muss ich aus accept() rausbekommen?!

Ist das dann das, was in int sock2 gespeichert ist?
Code:
[COLOR=seagreen]/* accept() - Die eingehende Verbindung annehmen */    socklen_t sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in remote_host;
    int sock2 = accept(sockfd, (struct sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

[EDIT]

Ich habe es jetzt mal so probiert, aber das addr ist offensichtlich noch falsch ...
Code:
[COLOR=seagreen]/* recv() - Senden und Empfangen mit TCP */
   [COLOR=black] char buf[1024];
    if (recv (sock2, buf, 1024, 0) == -1) {
        perror("recv()");
    }
    int x=0;
    printf("message: ");
    while (x!=1024) {
        printf("%c", buf[x]);
        x++;
    }
    printf("\naccepted connection from [%s:%d]\n", inet_ntoa(addr), ntohs(remote_host.sin_port));
[EDIT2]
So würde ich beim Compilieren keine Fehlermeldung mehr bekommen, aber ob das stimmt?
Code:
printf("\naccepted connection from [%s:%d]\n", inet_ntoa(remote_host.sin_addr), ntohs(remote_host.sin_port));
Wenn mir wer bestätigen könnte, dass das so hinkommt (auch semantisch!), dann könnte ich mir jetzt noch den tcp_client überlegen und dann könnten wir das Ganze mal testen :) :
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_server(int port) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

   [COLOR=seagreen] /* bind() - Den eigenen Port festlegen */    struct sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(port);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind()");
    }
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    socklen_t len;
    getsockname(sockfd, (struct sockaddr *)&my_addr, &len);
    printf("Port: %d\n", ntohs(my_addr.sin_port));

    [COLOR=seagreen]/* listen() - Auf eingehende Verbindungen warten */    if (listen(sockfd, 5) == -1) {
        perror("listen()");
    }

    [COLOR=seagreen]/* accept() - Die eingehende Verbindung annehmen */    socklen_t sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in remote_host;
    int sock2 = accept(sockfd, (struct sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

    [COLOR=seagreen]/* recv() - Senden und Empfangen mit TCP */    char buf[1024];
    if (recv (sock2, buf, 1024, 0) == -1) {
        perror("recv()");
    }
    int i=0;
    printf("message: ");
    while (i<1024) {
        printf("%c", buf[i]);
        i++;
    }
    printf("\naccepted connection from [%s:%d]\n", inet_ntoa(remote_host.sin_addr), ntohs(remote_host.sin_port));

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Textnachricht, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 
    int port;

    if (argv[1]=="TCP" && argv[2]=="Server") {
        port = atoi(argv[3];
        tcp_server(port);
    } 

    return 0;
}
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Moin,

sieht gut aus hab jetzt keine Fehler finden können. Wenn du mehrere Clients hats musst du halt accept +recv noch in eine Schleife packen.
Du Empfängst jetzt nur 1*1024 Byte, falls es aber mehr Nutzdaten sind werden nicht alle Empfangen. Und du gibst immer 1024 Byte aus, anstatt die Anzahl tatsächlich empfangener Bytes.

Code:
ssize_t msg_lenght;
char buf[1024];
if ((msg_lenght=recv (sock2, buf, 1024, 0)) == -1) {
    perror("recv()");
    }

int i=0;
printf("message: ");
while (i<msg_lenght;) {
    printf("%c", buf[i]);
    i++;
    }
printf("\naccepted connection from [%s:%d]\n", inet_ntoa(remote_host.sin_addr), ntohs(remote_host.sin_port));
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ich habe nur einen Client, aber der könnte auch mehr Nutzdaten senden, insofern danke für deinen Tipp!

Mein vorläufiger Client-Code sieht so aus:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_client(void) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    [COLOR=seagreen]/* connect() - Verbindung aufbauen */    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    [COLOR=darkorange][B]serv_addr.sin_port = htons(80);[/B]    serv_addr.sin_addr.s_addr = inet_addr("192.168.3.1");
   [COLOR=darkorange][B] struct[/B] [COLOR=darkorange][B]servent* serviceinfo = getservbyname("http", "tcp");[/B]    serv_addr.sin_port = serviceinfo->s_port;
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect()");
    }

    [COLOR=seagreen]/* send() und recv() - Senden und Empfangen mit TCP */   [B][COLOR=purple] char *msg = "Test-Nachricht.\n";[/B]
    int len = strlen(msg);
    if (send(sockfd, msg, len, 0) == -1) {
        perror("send()");
    }
   [COLOR=royalblue][B] char buf[1024];
    if (recv(sockfd, buf, 1024, 0) == -1) {
        perror("recv()");
    }[/B]
    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Texteingabe, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 

    if (argv[1]=="TCP" && argv[2]=="Client") {
        tcp_client();
    }

    return 0;
}
Dazu hätte ich vorerst folgende Fragen:

1.) Der Client soll ja laut Aufgabenstellung nur versenden, also kann ich die blauen Zeilen gleich mal löschen?!

2.) In der violetten Zeile muss die Nachricht hin, die ich an den Server senden will, aber das kann ja jedes Mal eine andere sein, also kann ich die nicht fix definieren. Wie sollte ich das geschickt lösen? Meine Idee wäre, in der main den Textstring (der ja als Parameter rein kommt) in einem char Feld zu speichern (kann ein char Feld überhaupt eine variable Größe haben?) und dieses an die Funktion tcp_client() zu übergeben und dort dann eben in der violetten Zeile als msg zu speichern. Nur ob das so geht?!

3.) In den orangen Zeilen ist "http" und der entsprechende Port "80" angegeben. Ich habe den Teil einfach übernommen, aber brauche ich das http-Zeug überhaupt? Ich hab's mal testweise "http" rausgelöscht gehabt aus der Funktion, sodass nur noch "tcp" dastand, aber da hat der gcc Compiler gleich gemeint zu wenige Parameter ... ???

[EDIT]
Nochmal kurz zu dem msg_length in tcpserver:
Mit ssize_t msg_length geht das mal wieder nicht. Ich hab's dann noch mit int probiert, ging aber auch nicht. Da hat's schon wieder irgendwas mit dem Datentyp:

Capture.JPG
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_server(int port) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    [COLOR=seagreen]/* bind() - Den eigenen Port festlegen */    struct sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(port);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind()");
    }
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    socklen_t len;
    getsockname(sockfd, (struct sockaddr *)&my_addr, &len);
    printf("Port: %d\n", ntohs(my_addr.sin_port));

    [COLOR=seagreen]/* listen() - Auf eingehende Verbindungen warten */    if (listen(sockfd, 5) == -1) {
        perror("listen()");
    }

    [COLOR=seagreen]/* accept() - Die eingehende Verbindung annehmen */    socklen_t sin_size = sizeof(struct sockaddr_in);
    struct sockaddr_in remote_host;
    int sock2 = accept(sockfd, (struct sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

    [COLOR=seagreen]/* recv() - Senden und Empfangen mit TCP */    [COLOR=royalblue][B]ssize_t msg_lenght;[/B]    char buf[1024];
    if (msg_length = recv(sock2, buf, 1024, 0) == -1) {
        perror("recv()");
    }
    int i=0;
    printf("message: ");
    while (i<msg_length) {
        printf("%c", buf[i]);
        i++;
    }
    printf("\naccepted connection from [%s:%d]\n", inet_ntoa(remote_host.sin_addr), ntohs(remote_host.sin_port));

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Textnachricht, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 
    int port;

    [COLOR=royalblue][B]if (argv[1]=="TCP" && argv[2]=="Server") {
        port = atoi(argv[3]);
        tcp_server(port);
    } [/B]
    return 0;
}
^^ Das will ich noch lösen bevor ich mir den tcpclient vornehme ...
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

1.) Ja kannst du löschen
2.) Dynamische länge geht wenn du den Speicher auch dynamisch mit malloc, calloc allokiert. Du kannst ja auch einfach eine Nachricht von der STDIN einlesen.
3.) keine Ahnung :)
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ok, danke! malloc/calloc kenne ich, allerdings habe ich es noch nie für ein char Feld verwendet. Wenn's aber geht, passt's. Ich seh' auch gerade, dass ich da scheinbar was falsch verstanden habe in der Aufgabenstellung: Die Textnachricht soll nicht als Parameter an main übergeben werden, sondern wohl per scanf() eingelesen werden?! Muss ich mal ausprobieren wie sich das machen lassen könnte, hab' da aber schon eine Idee ... :)

3.) Gut, solange es nicht nichts "böses" macht, kann das http von mir aus da bleiben.

Wegen meinem EDIT aus dem vorigen Posting muss ich mir auch noch was überlegen. Dein ssize_t funktioniert wohl leider nicht?!

[EDIT]
Mit scanf und malloc sieht das dann wohl so aus:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_client([COLOR=royalblue][B]char *data[/B]) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    [COLOR=seagreen]/* connect() - Verbindung aufbauen */    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    [COLOR=darkorange][B]serv_addr.sin_port = htons(80);[/B]    serv_addr.sin_addr.s_addr = inet_addr("192.168.3.1");
    [B][COLOR=purple]struct servent* serviceinfo = getservbyname("http", "tcp");[/B]
    [COLOR=purple][B]serv_addr.sin_port = serviceinfo->s_port;[/B]    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect()");
    }

    [COLOR=seagreen]/* send() - Senden mit TCP */    [COLOR=royalblue][B]char *msg = data;[/B]    int len = strlen(msg);
    if (send(sockfd, msg, len, 0) == -1) {
        perror("send()");
    }

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 
    [COLOR=royalblue][B]int size;
    char *data = (char*)malloc(size * sizeof(char));[/B]    
    if (argv[1]=="TCP" && argv[2]=="Client") {
        [COLOR=royalblue][B]printf("Please enter message: ");
        scanf("%s", &data);
        tcp_client(data);[/B]    }

    return 0;
}
^^ Aber ich muss ja trotzdem irgendeinen Wert für size angeben, oder? Blöd nur, dass ich erst nach dem scanf weiß, wieviele Zeichen wirklich eingegeben wurden.

[EDIT2]
Ich habe gerade irgendwie die Vermutung, dass ich die beiden violetten Zeilen komplett löschen kann und in die orange gehört der Port, den ich als Parameter an main und dann an tcp_client übergebe. Auch die IP des Servers soll nicht fix definiert, sondern übergeben werden. Muss ich mir noch überlegen. :)
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Kann mir bitte irgendwer mal in verständlichen Worten zu erklären versuchen, wie das programmiertechnisch geht, eine eingelesene IPv4-Adresse (In dotted-decimal-notation) in "einen Wert" umzuwandeln, mit dem ich dann weiterarbeiten kann?! Ich weiß nur, dass ich dafür irgendwie inet_aton() brauche, aber nicht, wie das genau geht. Jedenfalls muss ich die IPv4 Adresse als Parameter an die main übergeben, dort umwandeln und den umgewandelten Wert an die Funktion tcp_client() übergeben, oder?

So irgendwie wahrscheinlich:
Code:
server_ip = inet_aton(argv[3]);
Nur, von welchem Datentyp sollte "server_ip" sein? Und inet_aton() braucht laut Compiler mehr Parameter, nur was soll ich da noch reinhängen? Habe ja hier geschaut, nur sagt mir das nicht viel. const char *cp ist wohl die eingegeben IP Adresse, nur was ist der Rest? So klappt's jedenfalls nicht:

Capture.JPG

Wenn ich mit meiner Vermutung, siehe Vorposting, richtig liege, müsste sich so jedenfalls der tcp_client machen lassen:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_client(char *data, int port) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    [COLOR=seagreen]/* connect() - Verbindung aufbauen */    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port); 
    [COLOR=royalblue][B]serv_addr.sin_addr.s_addr = xxx;[/B] [COLOR=seagreen]// IP Adresse an Funktion übergeben und hier einfügen    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect()");
    }

    [COLOR=seagreen]/* send() - Senden mit TCP */    char *msg = data;
    int len = strlen(msg);
    if (send(sockfd, msg, len, 0) == -1) {
        perror("send()");
    }

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 
    int size, port;
    char *data = (char*)malloc(size * sizeof(char));
    
    if (argv[1]=="TCP" && argv[2]=="Client") {
        port = atoi(argv[4]);
        printf("Please enter message: ");
        scanf("%s", &data);
        tcp_client(data, port);
    }

    return 0;
}
^^ Dann müsste ich mir nur noch irgendwas schlaues für das int size in der main einfallen lassen. Ohne irgendeinen Größenwert wird das so eher nicht gehen?!
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Na du liest es als Char array ein, und machst dann ne Typeumwandlung. Was sonst?
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ Habe oben noch ein Bisschen rumeditiert. Bin ich der Sache näher gekommen? Siehe mein Code (im Bild) ...

[EDIT]
So würde ich mir den Client vorstellen. Kann wer was dazu sagen, ob die blau markierten Teile (und natürlich der Rest) stimmen:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef _WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif

void tcp_client([COLOR=royalblue][B]char *data[/B], [COLOR=royalblue][B]int port[/B], [COLOR=royalblue][B]int server_ip[/B]) {
    [COLOR=seagreen]/* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

    [COLOR=seagreen]/* connect() - Verbindung aufbauen */    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = [COLOR=royalblue][B]htons(port)[/B]; 
    serv_addr.sin_addr.s_addr = [COLOR=royalblue][B]server_ip[/B];
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect()");
    }

    [COLOR=seagreen]/* send() - Senden mit TCP */    [COLOR=royalblue][B]char *msg = data;[/B]    int len = strlen(msg);
    if (send(sockfd, msg, len, 0) == -1) {
        perror("send()");
    }

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(sockfd); 
}

[COLOR=seagreen]/* Parameter: UDP/TCP, Client, Server-IPv4-Adresse, Port */
/* Parameter: UDP/TCP, Server, Port */int main(int argc, char *argv[]) { 
    [COLOR=royalblue][B]int size, port, server_ip[/B][B];[/B]    char *data = (char*)malloc(size * sizeof(char));
    
    if (argv[1]=="TCP" && argv[2]=="Client") {
        [COLOR=royalblue][B]server_ip = inet_aton(argv[3], struct in_addr *s_addr);[/B]        [COLOR=royalblue][B]port = atoi(argv[4]);[/B]        printf("Please enter message: ");
        scanf("%s", &data);
        tcp_client(data, port, server_ip);
    }

    return 0;
}
^^ Beim Compilieren schaut's jedenfalls nicht so schlecht aus. Nur 1 Fehler, weil irgendwas mit dem struct in der main noch nicht passt:

Capture.JPG
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Du deklarierst ein Struct in einem Funktionsaufruf :ugly:

Code:
     [COLOR=royalblue][B]server_ip = inet_aton(argv[3], struct in_addr *s_addr);[/B]
es gibt ja zig Versionen von inet_aton inet_aton - Linux Command - Unix Command
entweder du machst inet_aton(argv[3], serv_addr.sin_addr); in main, da du aber serv_addr in main nicht hast würde ich einfach argv[3] an tcp_client() übergeben und in tcp_client() dann die zuweisung inet_aton(argv[3], serv_addr.sin_addr); machen.

Wegen Size nimm einfach eine feste Größ, hast ja genug Arbeitsspeicher :devil: einfach mal 4096 Byte oder so allokieren.
Oder du machst das so Dynamic String Input - The GNU C Library das ist aber halt kein ANSI C Standard

Code:
  char *data;   scanf ("%as",&data);
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

LOL. inet_aton ist ja mal nett :D

Ich hätte jetzt nicht erwartet, das es hierfür direkt nen bib gibt. So was würde ich kurz selbst runter hacken, aber gut, wenn man sich die Arbeit sparen kann :daumen:
 
Zurück