none
Server Client Echo RRS feed

  • Frage

  • Hallo Leute,
    Ich brauche eure Hilfe...

    Ich habe von der Schule aus ein Projekt zugewiesen bekommen und ich kann leider damit nichts anfangen.
    Leider bin ich absolut neu in der Programmierszene und habe leider auch keinen Schimmer wie sowas funktioniert.

    Ich versuche mich jetzt schon seit 4 Tagen in dieses Thema einzulesen, hat aber alles irgendwie keinen Erfolg. Ich verstehs einfach nicht :(

    Nun zu meiner Aufgabe:

    Ich soll mit Visual Studio einen Echo-Client und einen Echo-Server programmieren.

    Der Client liest Eingaben von der Konsole und schickt die Daten an
    einen Server. Der Server liest die Daten und schickt sie wieder zu dem Client
    zurück. Der Client gibt die Daten wieder an die Konsole aus. Selbstverständlich
    sollen diese Daten auch auf der Serverkonsole angezeigt werden. <o:p></o:p>

    Wenn nun an der Client
    Konsole Zeichen eingeben werden, sollten diese unverstümmelt wieder auf derselben
    Konsole ausgegeben werden (wie ein Echo...)
    <o:p></o:p>

    • Die Daten sollen erst nach der Eingabe eines Zeilenumbruchs als Echo zurückgeschickt werden. <o:p></o:p>
    • Das Programm soll es auch ermöglichen eine Textdatei vom Client zum Server zu übertragen.
      Der Inhalt dieser Textdatei soll dann wieder auf die Konsole des Client gesendet werden.  

    Kann mir bitte jemand helfen??

    Liebe Grüße Kerstin

    Donnerstag, 25. Juni 2015 11:58

Antworten

  • Hallo Kerstin

    Für den Server brauchst Du einen eigenen Thread, der auf Client-Verbindungen "hört" und sich bei Verbinden eines Clients gleich wieder selbst neu startet, damit ein weiterer Thread auf einen weiteren Client warten kann.

    UINT ServerThread(LPVOID pParam) {

    char recbuf[128];

    cfg_t *pCfg = (cfg_t*)pParam; // hier wird unteren anderem der WS (SOCKET) übergeben // jetzt auf den Client warten SOCKET WSH; sockaddr_in newaddr; int newlen = sizeof(newaddr); while (1) { // bevor wir den blockierenden Aufruf ACCEPT verwenden, schauen wir nach, ob er auch // erfolgreich verlaufen wird (also nicht blockieren wird). FD_SET fd = {1,pCfg->WS}; TIMEVAL tv = {1,0}; int ret = select(0,&fd,NULL,NULL,&tv); if (ret == SOCKET_ERROR) { return(0); // wir beenden die Sache } if (ret==1) break; // Erfolgreich } WSH = accept(pCfg->WS,(sockaddr*)&newaddr,&newlen); // der Client Request wird akzeptiert

    AfxBeginThread(ServerThread,pParam);

    if (WSH != INVALID_SOCKET) { int pos = 0; do { int rv = recv(WSH,&recbuf[pos],128-pos,0); if (rv > 0) { pos+=rv; // CR suchen for (int i = 0; i < pos; i++) { if (recbuf[i] == 13) { // Ende der Zeile send(WSH,recbuf,i,0); // Echo senden // Rest umkopieren memcpy(recbuf,&recbuf[i+1],128-i); pos -= i; } } } } while (rv != SOCKET_ERROR); } closesocket(WSH); return(0); }


    Dann muss der Server natürlich noch die Sockets aufsetzen

    // socket anlegen if ((pC->WS = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) != INVALID_SOCKET) { pC->addr.sin_family = AF_INET; // TCPIP pC->addr.sin_port = htons(port);// port pC->addr.sin_addr.S_un.S_addr= INADDR_ANY; // jeder darf sich mit uns verbinden if (bind(pC->WS,(struct sockaddr*)&pC->addr,sizeof(pC->addr)) != SOCKET_ERROR) { // binden if (listen(pC->WS,MAX_CSC_THREADS) != SOCKET_ERROR) { // und beginnen zu horchen // Server Thread starten

    AfxBeginThread(ServerThread,(LPVOID)pC); } } }

    Die pC Strukturen enthalten die SOCKETS und Addresstrukturen. Ich hab das hier aus bestehendem Code herausgekürzt. Lass es mal wirken

    FireHeart


    Donnerstag, 2. Juli 2015 06:58

Alle Antworten

  • Hallo Kerstin,

    Welche Besonderheiten des Verfahrens bereiten Dir Schwierigkeiten? Die Erstellung eines verbundenen Sockets, das Versenden der Daten oder das Lauschen auf Daten?

    Sieh Dir folgendes Codebeispiel an. Ich hoffe, dass es Dir von Nutzen sein wird:
    echo server example

    Zusätzlich möchte ich Dich auf diese Liste von relevanten Funktionen hinweisen, insbesondere auf accept, bind, connect, listen, socket:
    Winsock Functions

    Gruß,
    Dimitar


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Freitag, 26. Juni 2015 11:54
    Administrator
  • Hallo Kerstin

    Für den Server brauchst Du einen eigenen Thread, der auf Client-Verbindungen "hört" und sich bei Verbinden eines Clients gleich wieder selbst neu startet, damit ein weiterer Thread auf einen weiteren Client warten kann.

    UINT ServerThread(LPVOID pParam) {

    char recbuf[128];

    cfg_t *pCfg = (cfg_t*)pParam; // hier wird unteren anderem der WS (SOCKET) übergeben // jetzt auf den Client warten SOCKET WSH; sockaddr_in newaddr; int newlen = sizeof(newaddr); while (1) { // bevor wir den blockierenden Aufruf ACCEPT verwenden, schauen wir nach, ob er auch // erfolgreich verlaufen wird (also nicht blockieren wird). FD_SET fd = {1,pCfg->WS}; TIMEVAL tv = {1,0}; int ret = select(0,&fd,NULL,NULL,&tv); if (ret == SOCKET_ERROR) { return(0); // wir beenden die Sache } if (ret==1) break; // Erfolgreich } WSH = accept(pCfg->WS,(sockaddr*)&newaddr,&newlen); // der Client Request wird akzeptiert

    AfxBeginThread(ServerThread,pParam);

    if (WSH != INVALID_SOCKET) { int pos = 0; do { int rv = recv(WSH,&recbuf[pos],128-pos,0); if (rv > 0) { pos+=rv; // CR suchen for (int i = 0; i < pos; i++) { if (recbuf[i] == 13) { // Ende der Zeile send(WSH,recbuf,i,0); // Echo senden // Rest umkopieren memcpy(recbuf,&recbuf[i+1],128-i); pos -= i; } } } } while (rv != SOCKET_ERROR); } closesocket(WSH); return(0); }


    Dann muss der Server natürlich noch die Sockets aufsetzen

    // socket anlegen if ((pC->WS = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) != INVALID_SOCKET) { pC->addr.sin_family = AF_INET; // TCPIP pC->addr.sin_port = htons(port);// port pC->addr.sin_addr.S_un.S_addr= INADDR_ANY; // jeder darf sich mit uns verbinden if (bind(pC->WS,(struct sockaddr*)&pC->addr,sizeof(pC->addr)) != SOCKET_ERROR) { // binden if (listen(pC->WS,MAX_CSC_THREADS) != SOCKET_ERROR) { // und beginnen zu horchen // Server Thread starten

    AfxBeginThread(ServerThread,(LPVOID)pC); } } }

    Die pC Strukturen enthalten die SOCKETS und Addresstrukturen. Ich hab das hier aus bestehendem Code herausgekürzt. Lass es mal wirken

    FireHeart


    Donnerstag, 2. Juli 2015 06:58