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

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

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

    return 0;
}
Beim ersten Teil ist size nicht initialisiert (kompilier mal mit dem Argument -Wall, das zeigt alle Warnungen an, u. a. nichtinitialsierte Variablen).

Beim zweiten Teil ist die if-Abfrage falsch. Du kannst in C Strings nicht mit "==" vergleichen. Du musst dafür z. B. die strcmp aus der string.h nutzen
Code:
if (strcmp(argv[1], "TCP") == 0)
{
    /* argv[1] = TCP */
}
Beim dritten Teil kommt mir das "struct in_addr *s_addr" komisch vor. Das muss sicher "inet_aton(argv[3], &server_ip)" heißen.
Edit: Ah, wurde schon entdeckt ^^

Abgesehen davon, wenn du mit argv arbeitest, solltest du besser argc vorher kontrollieren, ob du überhaupt genügend Argumente hast, beispielsweise
Code:
if (argc < 3)
{
    printf("Fehler: Zu wenig Argumente.\n");
    return -1; /* exit */
}
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ Ok, vielen Dank an alle! Habe das jetzt alles noch so umgebastelt:
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=royalblue][B]char *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 = htons(port); 
    serv_addr.sin_addr.s_addr = [COLOR=royalblue][B]inet_aton(server_ip, serv_addr.sin_addr);[/B]    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 size1=4096, [COLOR=royalblue][B]size2=1024[/B], port;
    char *data = (char*)malloc(size1 * sizeof(char));
    [COLOR=royalblue][B]char *server_ip = (char*)malloc(size2 * sizeof(char));[/B]    
    if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            [COLOR=royalblue][B]server_ip = argv[3];[/B]            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            tcp_client(data, port, [COLOR=royalblue][B]server_ip[/B]);
        }
    }

    return 0;
}
^^ Nur ein Problem mit dem inet_aton() ist geblieben. Irgendwas stimmt mit dem zweiten Parameter immer noch nicht. Wenn ich siese Variante nehme ...
Code:
inet_aton(server_ip, &server_ip);
... dann kommt das:
&server_ip.JPG

Und wenn ich diese Variante nehme ...
Code:
inet_aton(server_ip, serv_addr.sin_addr);
... dann das:
serv_addr.sin_addr.JPG
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Für malloc/free (das man nicht vergessen sollte ;-)) musst do noch die stdlib.h includen.

Versuch mal das hier:
Code:
/* die Funktion erwartet einen Zeiger auf die inet_addr, also musst du auch einen Zeiger liefern */
inet_aton(server_ip, [B]&[/B]serv_addr.sin_addr);
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ Ok, so klappt das schon ganz gut! Ich hab's auch schon in ein File zusammengefügt, weil's ja so gelöst werden soll:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.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() - 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); 
}

void tcp_client(char *data, int port, char *server_ip) {
    [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); 
    serv_addr.sin_addr.s_addr = inet_aton(server_ip, &serv_addr.sin_addr);
    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 port, size1=4096, size2=1024;
    char *data = (char*)malloc(size1 * sizeof(char));
    char *server_ip = (char*)malloc(size2 * sizeof(char));

    if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Server")==0)) {
        if (argc!=4) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            port = atoi(argv[3]);
            tcp_server(port);
        }
    } else if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            server_ip = argv[3];
            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            tcp_client(data, port, server_ip);
            free(data);
            free(server_ip);
        }
    }

    return 0;
}
Nur das ssize_t msg_length passt noch nicht:

ssize_t msg_length.JPG

^^ Ich hätte ja spontan int dafür genommen?! Wieso muss das wieder von irgendeinem Struktur-Datentyp sein?
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Heißt das nicht size_t? ssize_t ist mir zumindest noch nicht untergekommen :D
Edit: ssize_t gibt es ja wirklich, wieder was gelernt ^^

Und das muss keine Struktur sein, sondern ist ein typedef (bei size_t kann z. B. ein unsigned int dahinter stecken). Ein typedef macht einen Datentyp nur unter anderem Namen verfügbar.
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Was typedef macht, weiß ich, aber size_t löst das Problem auch nicht ... :huh:

Capture.JPG

Langsam fällt mir kein passender Datentyp mehr dafür ein. socklen_t kann ich ja schon gar nicht nehmen, ein simples int eher auch nicht?!
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Rechtschreibfehler: du hast das th bei length vertauscht, das ssize_t ist aber ok ^^
Und bei der If-Abfrage danach fehlt auch noch ne Klammer: if ((msg_length = ...()) == -1) {...}.
Wobei ich mir jetzt, ohne es auszuprobieren, nicht sicher bin, ob die wirklich fehlt.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ Ah ja ... *facepalm*

Danke, so compiliert jetzt mal alles fehlerfrei. Jetzt muss ich das Ganze mal in den VMs testen, ob der Datentransfer per TCP funktioniert. Bin mir nur noch nicht ganz sicher, wie das gehen soll. Das C file in die Client- UND die Server-VM einfügen? Dann nur am Client mit den entsprechenden Parametern aufrufen? Mal ausprobieren ...
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

wollt nur mal anmerken: sehr intressant das alles :) weiter so, sonen krempel wollt ich mir auch ma irgendwann beibringen >< klingt ja alles urst verwurschtelt xD da kannst du mir dann mal helfen boss ^^
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Das Zusammenwurschteln von verschiedenen Konzepten und Beispielprogrammen ist was die Diskussion hier kompliziert erscheinen lässt. Da will jemand erst einmal eine funktionierende TCP-Kommunikation zum laufen bekommen und ihm wird direkt dynamische Speicheradressierung vorgeschlagen :klatsch:.

Eine gute Quelle(hab ich vorne schon mal verlinkt) nehmen und das mal gewissenhaft durcharbeiten sorgt imo für deutlich mehr Durchblick als sich von Anderen die Compilerfehler erklären zu lassen.
Danke, so compiliert jetzt mal alles fehlerfrei. Jetzt muss ich das Ganze mal in den VMs testen, ob der Datentransfer per TCP funktioniert. Bin mir nur noch nicht ganz sicher, wie das gehen soll. Das C file in die Client- UND die Server-VM einfügen? Dann nur am Client mit den entsprechenden Parametern aufrufen? Mal ausprobieren ...
Musst es halt auf der Client VM mit den Argumenten zum Start als Client und auf der Server VM mit den Server Argumenten füttern.

Wobei ein Rechner mit mehreren Terminals zum testen völlig ausreicht. Ob das TCP-Paket quer durchs Internet oder nur über den loopback geht ist deinem Programm eh egal.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Kann mich dem auch anschließen. An sich ist das kein großes Ding. Hab ich auch schon als Aufgabe gehabt in nem Übungszettel, und hatte das an nem WE gelöst. Hier haperts aber schon an gewissen Basics, nicht am eigentlichen Problem.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

wollt nur mal anmerken: sehr intressant das alles :) weiter so, sonen krempel wollt ich mir auch ma irgendwann beibringen >< klingt ja alles urst verwurschtelt xD da kannst du mir dann mal helfen boss ^^
"Verwurschtelt" finde ich das jetzt eigentlich gar nicht, zumindest soweit der Code jetzt ist. Gerade dadurch, dass jetzt alles in Funktionen unterteilt ist (kommen noch 2 dazu) und man über die Parameter an main recht gut steuern kann, was passieren soll, finde ich's relativ übersichtlich. Was das alles hier wahrscheinlich "verwurschtelt" erscheinen lässt, ist, dass wir mehr Programmieren als Netzwerktechnik diskutieren ... :ugly:

Ich muss mir jedenfalls noch gut anschauen, was eigentlich in den structs, auf die ständig irgendwie verlinkt/zugegriffen wird, drinnen steht. Der Rest ist mir schon halbwegs klar. Und viele der Variablen kann man sich ja mehr oder weniger frei benennen, damit man weiß, was das Zeug alles ist. Sieht man ja auch, dass das Ganze in fast jedem Tutorial anders heißt. Und darum orientiere ich mich auch an EINEM und baue keine Mischung aus mehreren.
Musst es halt auf der Client VM mit den Argumenten zum Start als Client und auf der Server VM mit den Server Argumenten füttern.

Wobei ein Rechner mit mehreren Terminals zum testen völlig ausreicht.
Ja, genauso habe ich das eh vor. Im Moment bin ich noch damit beschäftigt, das C File irgendwie in die Server VM reinzukriegen. Habe dazu ein Interface eth1 ins lokale Netzwerk geöffnet, aber dieses Interface will ums Verrecken keine IPv4 Adresse annehmen. Habe den Befehl schon zig mal probiert (sudo dhclient -4 eth1), rebootet, resettet ... immer wieder keine Adresse. Bin da noch am googeln ...
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Was das alles hier wahrscheinlich "verwurschtelt" erscheinen lässt, ist, dass wir mehr Programmieren als Netzwerktechnik diskutieren ... :ugly:
Genau das. Dir fehlen einfach einige Basics bzgl programmieren. Bitte nicht falsch verstehen, aber du machst am laufenden Band ziemlich heftige Fehler, die man so nicht machen sollte. Man merkt einfach, dass du absolut keine Erfahrung mit Linux Systemen hast, und auch ansonsten nicht viel mit C/C++ bisher scheinbar gemacht hast. Und dann kommen halt noch die VS-Anfänger Unzulänglichkeiten mit dazu. VS ist ne tolle Sache, aber doch bitte erst nachdem man die Basics kann...

Dazu machst du es dir noch unnötig kompliziert mit der VM. Mach dir nen Dualboot, das ist nen Aufwand von ner halben Stunde und gut ist....

Ansonsten kann ich nur sagen, dass Programmieren nicht etwas abtippen ist, sondern verstehen von Konzepten. Du willst einfach etwas nur reproduzieren. Es gibt aber imme eine millionen Wege wie man etwas lösen kann. Das ist ja das spannende an Programmierend. Man kann verdammt kreativ sein. Vorallem, wenn man etwas performant machen will. Darum gehts bei dir aber gar nicht. Du solltest erstmal das Konzept eines Sende-/Empfangsbuffers verstehen. Das hast du nämlich bis jetzt noch nicht, wie mir scheint auf Grund deiner Fragen.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Dazu machst du es dir noch unnötig kompliziert mit der VM. Mach dir nen Dualboot, das ist nen Aufwand von ner halben Stunde und gut ist....
Ich muss mit den VMs arbeiten, so, wie wir sie auf der Uni bekommen haben. Und obwohl ich jetzt schon alles manuell eingetragen habe auf der Server VM kann sich putty immer noch nicht hinverbinden. Ich habe keine Ahnung, wie ich as C File da sonst rein bekommen soll (abgesehen von alles händisch tippen) ... :wall:

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

Je nach VM Software solltest du über die Laufwerke, USB Sticks etc. weiter reichen können. Die musst du dann nur in der VM mounten.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ Auch alles schon probiert. Nur der Stick wird dann nicht gefunden, trotz mounten ... ich komme auf keinem Weg in diese verdammt VM rein ... :ugly:

Capture2.JPG

Wenn putty nicht geht, geht natürlich winSCP auch nicht. Network Bridge hat nichts gebracht. Shared Folders werden dann unter Linux in der VM wieder nicht gefunden. Und den USB-Stick mounten war jetzt auch meine letzte Idee, nur der wird auch nicht gefunden.

[EDIT]
Hab's gerade noch einmal probiert mit dem Stick. Da kommt dann sowas und da bleibt die VM hängen, bis ich das ganze mit Strg+c abbreche:

Capture.JPG

[EDIT2]
Habe noch ein Bisschen herumprobiert: Scheinbar kann der Stick nicht gemounted werden?!

Capture.JPG

[EDIT3]
Habe den Stick jetzt unter Windows auf FAT32 formatiert und jetzt kann er auch in Debian gemountet werden. Da muss man auch erst einmal draufkommen ... :schief:

Allerdings wird jetzt das C File als leeres File ohne Inhalt angezeigt. :wall:
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Auf den Client kann ich mich ja mit putty hinverbinden. Kann ich nicht irgendwie über die Client VM das C File an die Server VM schicken?

[EDIT]

Vergessen wir die VMs vorerst. Ich habe jetzt noch das ganze für UDP gemacht:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.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 udp_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]/* recvfrom() - Empfangen mit UDP */    ssize_t msg_length;
    char buf[1024];
    if (msg_length = [COLOR=royalblue][B]recvfrom[/B](sock2, buf, 1024, 0, [COLOR=royalblue][B](struct sockaddr *)&serv_addr, sizeof(struct sockaddr)[/B]) == -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); 
}

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

    [COLOR=seagreen]/* sendto() - Senden mit UDP */    char *msg = data;
    int len = strlen(msg);
    if ([COLOR=royalblue][B]sendto[/B](sockfd, msg, len, 0,[COLOR=royalblue][B] (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)[/B]) == -1) {
        perror("send()");
    }

    [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[]) {
    int port;

    if ((strcmp(argv[1], "UDP")==0) && (strcmp(argv[2], "Server")==0)) {
        if (argc!=4) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            port = atoi(argv[3]);
            udp_server(port);
        }
    } else if ((strcmp(argv[1], "UDP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            server_ip = argv[3];
            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            udp_client(data, port, server_ip);
            free(data);
            free(server_ip);
        }
    }

    return 0;
}
^^ Bei recvfrom() und sendto() kommen ja gegenüber recv() und send() noch 2 Parameter dazu: Adresse des Verbindungspartners und Größe der Struktur sockaddr?!

Beide Male wird's aber nicht &serv_addr sein, oder? Muss ich beim Server &remote_host schreiben?
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Habe jetzt alles in den VMs drinnen und das Ganze mit TCP auch gleich mal getestet. Beim Server-Part scheint alles soweit in Ordnung, nur der Client bleibt bei connect() hängen:

Capture.JPG
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.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, char *server_ip) {
    [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); 
    serv_addr.sin_addr.s_addr = inet_aton(server_ip, &serv_addr.sin_addr);
    [COLOR=royalblue][B]if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect()");
    }[/B]
    [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 port, size1=4096, size2=1024;
    char *data = (char*)malloc(size1 * sizeof(char));
    char *server_ip = (char*)malloc(size2 * sizeof(char));

    if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Server")==0)) {
        if (argc!=4) {
            printf("Parameters missing or too many parameters!\n");
            return -1;
        } else {
            port = atoi(argv[3]);
            tcp_server(port);
        }
    } else if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing or too many parameters!\n");
            return -1;
        } else {
            server_ip = argv[3];
            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            tcp_client(data, port, server_ip);
            free(data);
            free(server_ip);
        }
    }

    return 0;
}
^^ Normal heißt ja Segmentation Fault, dass versucht wird, auf einen Speicher zuzugreifen, auf den physikalisch kein Zufriff besteht, aber wo soll denn das bei mir der Fall sein? An den mallocs kann's doch nicht liegen?! Und die Größen von size1 und size2 müssten doch auch locker reichen?!

PS: Server-VM und Client-VM können sich ganz normal pingen.
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

@ Mods
Sorry für die vielen Posts hintereinander, aber sonst sieht keiner, dass im Thread was weitergeht. :)

@ Topic
Habe jetzt sowohl aus dem TCP- als auch dem UPD-Code sämtliche Syntaxfehler raus. Bin auch schon die ganze Zeit am Testen, ob die Übertragungen klappen, aber zur Zeit kämpfe ich noch mit folgenden Problemen:

TCP:
- Server scheint in Ordnung
- Client scheitert bei connect()

Capture.JPG
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.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 */    ssize_t msg_length;
    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); 
}

void tcp_client(char *data, int port, char *server_ip) {
    [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); 
    serv_addr.sin_addr.s_addr = inet_aton(server_ip, &serv_addr.sin_addr);
    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 port, size1=4096, size2=1024;
    char *data = (char*)malloc(size1 * sizeof(char));
    char *server_ip = (char*)malloc(size2 * sizeof(char));

    if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Server")==0)) {
        if (argc!=4) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            port = atoi(argv[3]);
            tcp_server(port);
        }
    } else if ((strcmp(argv[1], "TCP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            server_ip = argv[3];
            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            tcp_client(data, port, server_ip);
            free(data);
            free(server_ip);
        }
    }

    return 0;
}
UDP:
- Server scheitert an recvfrom()
- Client meint wie bei TCP "Segmentation fault"

Capture1.JPG Capture2.JPG
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.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 udp_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]/* recvfrom() - Empfangen mit UDP */    ssize_t msg_length;
    struct sockaddr_in remote_host;
    char buf[1024];
    if (msg_length = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr *)&remote_host, &len)) == -1) {
        perror("recvfrom()");
    }
    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); 
}

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

    [COLOR=seagreen]/* sendto() - Senden mit UDP */    char *msg = data;
    int len = strlen(msg);
    struct sockaddr_in serv_addr;
    if (sendto(sockfd, msg, len, 0, (struct sockaddr *)&serv_addr, &len) == -1) {
        perror("sendto()");
    }

    [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 port, size1=4096, size2=1024;
    char *data = (char*)malloc(size1 * sizeof(char));
    char *server_ip = (char*)malloc(size2 * sizeof(char));

    if ((strcmp(argv[1], "UDP")==0) && (strcmp(argv[2], "Server")==0)) {
        if (argc!=4) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            port = atoi(argv[3]);
            udp_server(port);
        }
    } else if ((strcmp(argv[1], "UDP")==0) && (strcmp(argv[2], "Client")==0)) {
        if (argc!=5) {
            printf("Parameters missing of too many parameters!\n");
            return -1;
        } else {
            server_ip = argv[3];
            port = atoi(argv[4]);
            printf("Please enter message: ");
            scanf("%s", &data);
            udp_client(data, port, server_ip);
            free(data);
            free(server_ip);
        }
    }

    return 0;
}
^^ Wenn mir bitte wer helfen könnte, diese Fehler im Code zu beheben, wäre ich echt sehr dankbar! Dann könnte ich nämlich den TCP- und den UDP-Code in ein C File zusammenfügen und endlich mit der Aufzeichnung der Übertragung beginnen ...

Ich bin eh selbst auch schon den ganzen Tag am googeln bezüglich dieser Fehler, aber ich komme dabei nicht so recht weiter. Wo komme ich denn bitte auf ein Speichersegment, auf das kein physikalischer Zugriff besteht? Das soll "Segmentation fault" doch bedeuten?! :huh:
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

wieso machste das eigentlich in ner vm? vllt liegt da ja der hase begraben. oder es liegt am linux. hatte mal sone rettungs-heft-dvd nutzen wollen, da konnte die pfeiffe nichma auf die laufwerke zugreifen. aber wie ich da irgendwelche berechtigungen geb hatte sich mir auch ned erschlossen. naja, ich steh mit linux eh auf kriegsfuss >< bin einfach zu sehr an windows gewöhnt um komm ums verrecken ned damit klar.

jedenfalls meine laienhaften vermutungen:
- linux hat zugriffsprobs/fehlende rechte auf irgendwas
- die vm hat zugriffsprobs/fehlende rechte auf irgendwas

da auch meine fragen: geht das nur unter linux dann oder? wäre ganz kuhl, wenn das auch unter windoof laufen würde ^^ und: gibts bei sowas unterschiede zw xp und win7 als bsp? also halt die verschiedenen versionen von winblöd. oder is das vereinheitlicht? was nich verkehrt wäre, aus meiner bedürfnis-sicht :D und noch ne frage: bei älteren games gabs ja ne exe für dedicated server. da hab ich auch öfter ma nen server aufm eignen rechner gestartet und bin mit der (zweiten exe) client exe dann drauf gejoined - und andre mittels hamachi hinterher usw. is das hiermit auch möglich?

weil die ganze problematik würd ich ja gern für mein ogl projekt adaptieren. soll ja auch ma irgendwann nen server/client programm werden.
 
Zurück