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

B

boss3D

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

Hi @ all!

Folgende Aufgabe:

Aufgabe a.JPG Aufgabe b.JPG

Dazu haben wir auch 3 virtuelle Maschinen (NET1UE-Client, NET1UE-Server, NET1UE-Router) bekommen, alle 3 mit Debian. Ich arbeite dabei mit dem VMWare Player und putty. In die Client und die Server VM muss ich dann meinen Code einfügen und dann ausführen. Dann müsste das laufen.

So sieht der Netzplan aus:

Netzplan.JPG

Und so natürlich eine TCP/UDP Datenübertragung:

TCP.JPG UDP.JPG

Entsprechend der Aufgabe a habe ich jetzt erstmal die nötigen Funktionen versucht nach diesem HowTo zu programmieren, v.a. weil's da auch recht schön erklärt wird, was eigentlich wo passiert. :)

Hier mein aktueller Code:
Code:
#include <stdio.h>
#include <errno.h>
#include <string>
#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

int main(int argc, char *argv[]) {
    [COLOR=seagreen]/* Client: */
   [COLOR=seagreen] /* socket() - Socket anfordern */    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket()");
    }

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

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

    char buf[1024];
    if (recv (sockfd, buf, 1024, 0) == -1) {
        perror ("recv()");
    }

    [COLOR=seagreen]/* sendto() und recvfrom() - Senden und Empfangen mit UDP */    [COLOR=red][B]XXX[/B]

    [COLOR=seagreen]/* close() - Socket freigeben */    int close(int fd); [COLOR=seagreen]/* closesocket() für Windows */
    [COLOR=seagreen]/*-----------------------------------------------------------------*/    [COLOR=seagreen]/* Server: */
    [COLOR=seagreen]/* bind() - Den eigenen Port festlegen */    sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(5000);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sockfd, (sockaddr *)&my_addr, sizeof(sockaddr)) == -1) {
        perror ("bind()");
    }
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    [B][COLOR=red]socklen_t[/B] len;
    getsockname(sockfd, (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 */    [COLOR=red][B]socklen_t[/B] sin_size = sizeof (sockaddr_in);
    sockaddr_in remote_host;
    int sock2 = accept (sockfd, (sockaddr *) &remote_host, &sin_size);
    if (sock2 == -1) {
        perror ("accept()");
    }

    return 0;
}
^^ Nicht wundern wegen der vielen Bibliotheksfunktionen. Da ich im Visual Studio programmiere, musste alles für Windows rein und weil's dann aber später unter Debian laufen soll, auch alles für Linux/Unix. Durch's if/else kann der Compiler eh schön unterscheiden und sich das holen, was er braucht.

So, und jetzt zu meinen Fragen:

1.) Wo die drei roten fetten XXX sind, was genau muss dahin? Das ist das einzige, was ich aus dem HowTo nicht wirklich herauslesen konnte. Da stand nur irgendwas von wegen so ähnlich wie's normale send() und recv(), aber mit ein paar zusätzlichen Zeilen?!

2.) socklen_t wird mir im Visual Studio rot unterwellt und als undefined beschrieben. In welcher Bibliotheksfunktion, die ich noch nicht eingebunden habe, soll das denn drinnen sein? Durch googeln bin ich auch nicht schlauer geworden. Wenn's allerdings nur unter Windows nicht gefunden wird, unter Linux dann aber schon, wäre es eh halb so wild.

3.) Was ich dann noch bräuchte, wäre irgendwas, wo der User über Parameter, die direkt an die main übergeben werden, auswählen kann, ob er Client oder Server sein will und ob ein beliebiger Text (ebenfalls als Parameter) per TCP oder UDP übertragen werden soll. Auch der entsprechende Port soll beim Server mitübergeben werden. Eben so, wie's in der Angabe steht. Da weiß ich noch nicht so recht, wie ich das machen soll ...

Irgendwie so vielleicht:
Code:
int main(int argc, char *argv[]) {
    if (argv[1]=="Client") {
        if (argv[2]=="TCP") {
            [COLOR=seagreen]// Client-TCP Code        } else if (argv[2]=="UDP"){
            [COLOR=seagreen]// Client UDP-Code        }
    } else if (argv[1]=="Server") {
        if (argv[2]=="TCP") {
            [COLOR=seagreen]// Server-TCP Code        } else if (argv[2]=="UDP"){
            [COLOR=seagreen]// Server-UDP Code        }
    }
    
    return 0;
}
^^ Nur, dass das so enorm viel Code werden würde, weil ich ja fast alles dann mindestens doppelt drinne hätte. Das kann's ja nicht sein?!

4.) Der Lehrer hat gemeint, einen wirklich minimalen Code für diese Aufgabe könnte man auch mit ~ 40 Zeilen schreiben, sodass der immer noch die Aufgabenstellung erfüllt. Ergo muss ich ja jede Menge "unnützes" Zeug drinnen haben?! Kann mir da jemand bitte beim "Ausmisten" helfen?! Was brauche ich denn alles eigentlich gar nicht? Im Übrigen ist der Code aus dem HowTo wahrscheinlich eh nicht 1:1 für meine Aufgabenstellung brauchbar. Hier und da (z.B. bei den IP-Adressen --> siehe Netzplan oben) bräuchte ich auch noch ein Bisschen Hilfe beim Anpassen, bitte.

Danke für baldige Antworten!
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

1. Ich würde in die main() eine Art Menü machen, dass die ganzen Eingaben erwartet. Je Nach Eingabe (TCP oder UDP? Client oder Server?) würde ich dann eine Funktion starten. Also zum Beispiel TcpServer(int Port). So ist alles schön getrennt.

Das gehört in sendto():
-Parameter 1: Socket über den wir die Daten senden wollen
-Parameter 2: Pointer auf einen Buffer der die zu sendenden Daten enthält
-Parameter 3: Wieviele Zeichen von buf gesendet werden sollen
-Parameter 4: benötigen wir nicht, auf 0 setzten
-Parameter 5: in unserem Falle ein Pointer auf eine SOCKADDR_IN Struktur die Informationen über den Zielrechner enthält
-Parameter 6: länge von to, in userem Fall sizeof(SOCKADDR_IN)

(Quelle: Winsock Tutorial: UDP)

2. Weiß ich leider nicht.

3. Ich wiederhole nochmal meinen Vorschlag, mach' es mit verschiedenen Funktionen. Das ist auch effizienter. So fallen die ganzen if() weg.

4. Ja, wenn man Schleifen Beispielsweise so schreibt (also ohne { bzw. } - Liest nur die erste Nachfolgende Zeile in einer Schleife):

for(int WasWeißIch; WasWeißIch < 0; WasWeißIch++)
Anweisung;

Mach's lieber lang und übersichtlich, scheiß drauf wie viele Zeilen du schreibst, du musst es verstehen, es muss effizient sein und du solltest es auch in einigen Monaten noch verstehen können (Kommentare!).
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ok, danke schon mal für die Antwort! Ich bin mir nicht sicher, ob ich alles kapiert habe, und da ich gerade in der Klausurwoche bin, kann ich mich im Moment auch nicht mit der Aufgabe beschäftigen. Ich hab's nur jetzt schon reingestellt, damit vielleicht mehrere Leute was hilfreiches posten bis ich dann Zeit habe, das fertig zu machen. :)

Sobald ich mich wieder darum kümmee, tauchen sicher noch genug Fragen auf ...

^^ Ich melde mich dann wieder.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Zu 2.

Du programmierst auf Windows, und hast damit nicht zwingend die Linux Sourcen. Ich weiß jetzt nicht 100%, ob das in den Linux-kerner-Sourcen drin ist, bin mir da aber relativ sicher.

PS:
Ich hab mal google gefragt. Direkt der erste Link :schief:<sys/socket.h>

Wenn du irgendwas "xy_t" findest, dann ist das eigentlich immer ein Datentype. Meist/Immer sind das portable Datentypen, die dafür sorgen, das es egal ist, ob man auf einer 32 oder 64Bit Maschine das Zeug laufen lässt.

Du musst also "nur" die <sys/socket.h> includieren. Die wirst du unter Windows aber nicht haben, es sei denn du lädst dir die Kernel-Sourcen runter.

Wenn du für Linux entwickelst, solltest du auch UNTER/AUF Linux entwickeln. Das macht es sehr viel einfacher, zumal man die Sachen auch gleich testen kann. In dem Zuge kannst du dir auch mal gleich "Makefiles" durchlesen, das ist am Anfang zwar etwas seltsam, macht die Arbeit aber VIEL einfacher und schneller, wenn man mal weiß, wie Makefiles zu bauen sind.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ich habe das Ganze jetzt auf 4 Funktionen verteilt. Ein paar Fragen hätte ich erst einmal zum TCP Server ...
Code:
#include <stdio.h>
#include <errno.h>
#include <string>
#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 */    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, (sockaddr *)&my_addr, sizeof(sockaddr)) == -1) {
        perror("bind()");
    }
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    [COLOR=royalblue][B]socklen_t len;
    getsockname(sockfd, (sockaddr *)&my_addr, &len);
    printf("Port: %d\n", ntohs(my_addr.sin_port));[/B]
    [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(sockaddr_in);
    sockaddr_in remote_host;
    int sock2 = accept(sockfd, (sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

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

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

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

    if (argv[1]=="TCP" && argv[2]=="Server") {
        port = *argv[3];
        tcp_server(port);
    } else if (argv[1]=="TCP" && argv[2]=="Client") {
        tcp_client();
    } else if (argv[1]=="UDP" && argv[2]=="Server") {
        udp_server();
    } else if (argv[1]=="UDP" && argv[2]=="Client") {
        udp_client();
    }

    return 0;
}
1.) Bei den ersten 3 fetten blauen Zeilen: Brauche ich das eigentlich, wenn ich eh den Port als Parameter an main und danach an die Funktion tcp_sever() übergebe? Oder ist das der port, den bind() festlegt und nicht der, den ich übergebe?

2.) Laut Aufgabe a (siehe Startposting) soll ja der TCP Sever eine Textnachricht vom Client erhalten und diese ausgeben. Wo genau muss ich die Ausgabe reinbasteln? Ich vermute mal, in send() und recv()?! Dann brauche ich ja dort die fette blaue Zeile nicht, oder? Bzw. ich müsste char *msg die übertragene Textnachricht zuweisen und dann msg ausgeben lassen?! Wie genau mache ich das?
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Moin,
die Ausgabe musst du nach recv machen (bedenke aber das es sich um eine Bytestream Übertragung handelt) . Ich sehe aber gerad einen ganz anderen Fehler bei dir Send und Recv müssen mit deinem neuen Socketdesktriptor (der von Accept zurückgegeben wird ) arbeiten nicht mit dem alten.

Deine erste Frage versteht ich nicht ganz. Den Port setzt du ja in deinem Struct und das übergibst du an Bind, danach lässt sich der Port auf den die Nachrichten empfangen werden sollen nicht mehr ändern. Aber mir sagt jetzt auch die Funktion getsockname() nichts, die habe ich selber bei meinen TCP/ UDP Programmen fürs Studium nicht benötigt. Btw. Studierst du auch AI ? Die Aufgabenstellung ist aufjedenfall fast so wie bei mir :)

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

Ah, du meinst sock2 statt sockfd?! Gut, und für die Ausgabe muss ich vermutlich den Inhalt des Buffers ausgeben, oder? Was mache ich dann mit diesem msg? Das brauche ich dann ja für nichts mehr, oder?
Code:
    [COLOR=seagreen]/* send() und recv() - Senden und Empfangen mit TCP */    char *msg = "Testmessage.\n";
    int len = strlen(msg);
    if (send(sock2, msg, len, 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++;
    }
^^ Oder muss ich die übertragene Nachricht in msg speichern und dann msg ausgeben?

BTW: Was ist AI? Ich studiere IT Security. :)

[EDIT]

Ein Problem bleibt noch: Beim Compilieren unter Linux (gcc -o tcpserver tcpserver.c) werden jede Menge Syntax-Fehler gefunden, die Visual Studio unter Windows nicht findet.
Code:
#include <stdio.h>
#include <errno.h>
#include <string>
#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 */    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, (sockaddr *)&my_addr, sizeof(sockaddr)) == -1) {
        perror("bind()");
    }
    [COLOR=seagreen]/* Zugewiesenen Port ermitteln: */    socklen_t len;
    getsockname(sockfd, (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(sockaddr_in);
    sockaddr_in remote_host;
    int sock2 = accept(sockfd, (sockaddr *)&remote_host, &sin_size);
    if (sock2 == -1) {
        perror("accept()");
    }

    [COLOR=seagreen]/* send() und recv() - Senden und Empfangen mit TCP */    char *msg = "Testmessage.\n";
    int len = strlen(msg);
    if (send(sock2, msg, len, 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++;
    }

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

[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 = *argv[3];
        tcp_server(port);
    } 

    return 0;
}
Capture.JPG

^^ Wie bringe ich die weg? Ich sehe da selbst gar keine Fehler in den Zeilen wo gcc meint, da würde was nicht passen. :huh:

Und bevor wieder einer meint, ich solls gleich unter Linux programmieren: Ich habe hier nur eine Debian VM ohne grafische Oberfläche. Geht daher irgendwie schlecht.
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Mit nano kann man durchaus brauchbar coden ;).
Davon abgesehen ist eine VM mit nem Linux inklusive grafischer Oberfläche schnell aufgesetzt.(bzw. mit ein apt-get install "gewünsche Oberfläche" sollte nach ner kleine Installationsorgie auch auf der vorhandene VM eine GUI auftauchen).

Zu deinen Problemen: sockaddr_in ist ein struct, also muss das da auch stehen . Die anderen Fehler beziehen sich in erster Linie auf die Folgen von der falschen Initialisierung an der Stelle.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

^^ So ungefähr bin ich eh bis jetzt auch schon vorgegangen: Mit putty drauf auf die VM, dann mit nano ein leeres C file erstellen und über putty den Code aus dem Visual Studio da rein kopieren ...

Ich habe auch vor 3 Tagen Debian mit GUI in einer VM installiert, weil ich mir gedacht hatte, gut, da dann noch Eclipse drauf und es kann los gehen, aber ich hab's um's Verrecken nicht hingebracht, das nötige C-Plugin zu installieren, sodass ich Eclipse überhaupt für C Code hätte nutzen können.

[EDIT]
Die fehlenden struct Wörter habe ich noch hinzugefügt. Das hat schon mal viele Fehler behoben. Nur 4 sind mir geblieben, wo ich nicht weiß, was da jetzt wieder nicht passt:
Code:
#include <stdio.h>
#include <errno.h>
#include <string>
#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: */    struct 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 */    struct 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]/* send() und recv() - Senden und Empfangen mit TCP */    char *msg = "Testmessage.\n";
    int len = strlen(msg);
    if (send(sock2, msg, len, 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++;
    }

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

[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 = *argv[3];
        tcp_server(port);
    } 

    return 0;
}
Capture.JPG

Und wenn wir die noch wegbringen, bleibt noch das mit der Ausgabe des empfangenen Texts zu klären. Dann müsste zumindest der TCP-Server Teil mal fertig sein?!
 
Zuletzt bearbeitet:
AW: [C] Socket für TCP/UDP Übertragung programmieren

Moin,
AI Ist Angewandte Informatik.
Code:
 [COLOR=seagreen]/* send() und recv() - Senden und Empfangen mit TCP */     
char *msg = "Testmessage.\n";     
int len = strlen(msg);     
if (send(sock2, msg, len, 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++;     
}
vor send muss die Nachricht in msg stehen und nach recv steht die empfangene Nachricht in buf.

Zu deinen Fehlern:
Wegen dem strlen versuchs mal mit #include <string.h> anstatt #include <string>.
Änder vll mal den Typ von len nach size_t .
Zu sin_size du musst sin_size = sizeof(remote_host).
The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; on return it will contain the actual size of the peer address.
Linux Howtos: manpages: accept(2)


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

Ein Problem bleibt noch: Beim Compilieren unter Linux (gcc -o tcpserver tcpserver.c) werden jede Menge Syntax-Fehler gefunden, die Visual Studio unter Windows nicht findet.
Ja, weil da auch Syntaxfehler SIND! Visual Studio ist nur EXTREM umgänglich, was eigentlich falschen Code anbelangt... Das heißt aber nicht, das in größeren Projekten dann auch VS die Sachen nicht mehr packt und scheise baut. Genau so, das nicht irgend ein Mist während der Laufzeit passiert...

Deswegen soll man auch nicht den VS benutzen, wenn man anfängt, und in der Uni schon gleich 10 mal nicht... Dein Programmierstiel wird da einfach verdorben....


^^ Wie bringe ich die weg? Ich sehe da selbst gar keine Fehler in den Zeilen wo gcc meint, da würde was nicht passen. :huh:
Indem du den ersten Fehler suchst, und dann google bemühst... Und nein, das ist kein Scherz. Das muss man lernen, wie man nach Fehlermeldungen googeld. Mit der Zeit weißt du dann auch so ~10 Seiten, die die Standardanlaufstellen für gewisse Fehler sind. Das soll jetzt nicht heisen, das man nicht fragen darf, aber das hier sind keine wirklich schweren Fehler, UND du studierst, also solltest du solche Fehler selbst finden können. Ich seh da aber schon negative Einflüsse von VS...

Und bevor wieder einer meint, ich solls gleich unter Linux programmieren: Ich habe hier nur eine Debian VM ohne grafische Oberfläche. Geht daher irgendwie schlecht.
Für was braucht man bitte ne grafische Oberfäche zum programmieren? Klar, die Syntaxvervollständigung unter VS ist cool, aber bei den kleinen Projekten, die du hast, ist das voll fürn Arsch. Das kann man sich noch merken. Unter Linux entweder nano, oder vim verwenden. Ich nutze ja vim, und das kann man auch dazu bringen, einem die möglichen Variablennamen anzuzeigen. Ist zwar etwas Aufwand ein zu richten, weshalb ich es noch nie gemacht habe, da es sich für mich nie gelohnt hat, man kann es aber machen.

Entwickel einfach gleich auf Linux, dann hast du viele Probleme weniger. Von Windows -> Linux ist oft nicht einfach zu portieren, weil man "dank" VS geschlampt hat. Linux -> Windows ist die portierung SEHR einfach. Das geht meist ohne jegliches Problem.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Bei dem Ansatz, den du da verfolgst (In VS schreiben, dann "nach gcc kopieren") hast du das Problem, dass Visual Studio von Haus aus im C++ Modus arbeitet, während gcc C erwartet (g++ ist für C++). Und in C geht einiges nicht, was in C++ geht ;-) Ein paar Beispiele:
Code:
// In C++ (und C neueren Datums; C99?) ok, in C nicht.
for (int i = 0; i < count; ++i)
{
    ...
}

/* Valider C Code */
/* (Variablen müssen vor allen anderen Instruktionen deklariert werden) */
int i;
for (i = 0; i < count; ++i)
{
    ...
}


typedef struct Bla
{
    int foo;
    int bar;
} Bla_t;


void func1()
{
    struct Bla meinBla; /* In C und C++ ok */
    Blat_t meinBla2; /* Auch in C und C++ ok, da typedef */
    Bla meinBla3; /* Ok in C++, C mag das so nicht */
}
Wie gesagt, einige Dinge funktionieren in C wenn man einen neueren Standard auswählt (bspw. C99), aber da muss man halt auch dran denken. Abgesehen davon ist, wie Skysnake schon sagte, VS auch äußerst gnädig was Fehler angeht. Linux + Texteditor + gcc ist zum Verständnis wesentlich besser geeignet ;)
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Hey, ich hab ja auch gemeint mit VS anfangen zu müssen.... VOR dem Studium halt...

Die Quittung dafür habe ich im Studium bekommen, wo ich dann knapp ein Jahr gebraucht habe, um die Schnitzer aus VS aus meinem Kopf raus zu bekommen... Das hätte ich mir wirklich sparen können...
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Code:
[COLOR=seagreen]/* send() und recv() - Senden und Empfangen mit TCP */     
char *msg = "Testmessage.\n";     
int len = strlen(msg);     
if (send(sock2, msg, len, 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++;     
}
vor send muss die Nachricht in msg stehen und nach recv steht die empfangene Nachricht in buf.
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 ...
Zu deinen Fehlern:
Wegen dem strlen versuchs mal mit #include <string.h> anstatt #include <string>.
Ok, das hat das warning und einen error weggebracht.
Änder vll mal den Typ von len nach size_t .
Dann kommt die gleiche Meldung, nur diesmal eben für size_t:
Capture2.JPG
Zu sin_size du musst sin_size = sizeof(remote_host).
Damit kommen nur noch mehr Fehlermeldungen:
Capture.JPG
Deswegen soll man auch nicht den VS benutzen, wenn man anfängt, und in der Uni schon gleich 10 mal nicht... Dein Programmierstiel wird da einfach verdorben....
Mag ja sein, dass du recht hast, aber wir haben Visual Studio sogar von der Uni bekommen und ein ganzes Semester lange damit Programmieren gelernt. ;)
Indem du den ersten Fehler suchst, und dann google bemühst... Und nein, das ist kein Scherz. Das muss man lernen, wie man nach Fehlermeldungen googeld.
Ich hab gegoogelt bevor ich gepostet habe. Hätte ich die Fehler dadurch beheben können, würde ich ja hier nicht schreiben.
Bei dem Ansatz, den du da verfolgst (In VS schreiben, dann "nach gcc kopieren") hast du das Problem, dass Visual Studio von Haus aus im C++ Modus arbeitet, während gcc C erwartet (g++ ist für C++). Und in C geht einiges nicht, was in C++ geht
So schlau bin ich schon! Ich habe natürlich bei Compiler im VS "C" eingestellt und auch an den Filenamen ein .c angehängt. :)

Außerdem schreibe ich jetzt den Code eh nur mehr im Notepad++ und kopiere Änderungen via putty in mein nano file in der VM rein ... oder mache kleinere Änderungen gleich dort.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

GZ, du hast nicht verstanden, was er meinte...

Es gibt mehrere C Standards. Der GCC nimmt im normalfall der restregtivsten. Du darst da z.B. Variablen nur am Anfang definieren usw usw.

Ein
Code:
for(int i=0; i<10; i++)
funktioniert da z.B. gar nicht zwingend. Du musst vorher C99 (oder wie das auch noch immer heisen mag) aktivieren. Erst dann sind solche Sachen auch mit dem GCC möglich.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ja, das vermute ich momentan auch. Du musst deine Variablen am Anfang der Funktion deklarieren, mittendrin geht bei klassischem C nicht.
Code:
void foo()
{
    ...
    size_t len; /* das geht in klassischem C nicht! */
    ...
}

void foo()
{
    size_t len; /* Variablen müssen vor allen Instruktionen deklariert werden */
    ...
}
Da du die Variablen im laufenden Code deklarierst, kann es sein, dass er die deshalb nicht findet. Die Fehlermeldungen bei C/C++ sind manchmal nicht ganz so aussagekräftig, wie man das vielleicht gern hätte.
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

und deswegen meinte ich ja "man muss lernen Fehlermeldungen zu googlen". Ich sitz auch oft genug vorm PC und frag mich, was denn jetzt wieder mal in die Hosen geht...

Geil wirds vor allem, wenn man MB weise Fehlermeldungen bekommt :ugly: DAS ist lustig zu debuggen... Und teilweise ist es dann nur nen popel Fehler in irgend einer Libary oder so :-_-:
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

und deswegen meinte ich ja "man muss lernen Fehlermeldungen zu googlen". Ich sitz auch oft genug vorm PC und frag mich, was denn jetzt wieder mal in die Hosen geht...
Ich bin mir ziemlich sicher, dass es die Meldung genau so gibt, wenn man vergisst, einen Header einzubinden. Schön sind dann auch die von Visual Studio ins Deutsche übersetzten Fehlermeldungen *hust*

Geil wirds vor allem, wenn man MB weise Fehlermeldungen bekommt :ugly: DAS ist lustig zu debuggen... Und teilweise ist es dann nur nen popel Fehler in irgend einer Libary oder so :-_-:
Japp, fehlendes Include(-verzeichnis) oder ne Library vergessen und 15.687 Fehlermeldungen bestaunden :ugly:
 
AW: [C] Socket für TCP/UDP Übertragung programmieren

Ne, ich mein schon ECHTE Fehler in ner Libary ;)

DAS ist ein Spaß bei MPI Programmen :lol:
 
Zurück