Hilfe beim Client/Server...



  • Hallo Leute, ich habe ein Client und Server. Der Client übergibt dem Server ein Befehl der dann eine bestimmte *.exe startet. Diese Ausgabe des Befehls wird vom Server an den Client umgeleitet. Das Problem ist, dass die Ausgabe vom Server zu spät beim Client ankommt, d.h. wenn ich ein Befehl eingabe und Enter drücke, dann kommt nicht sofort die Ausgabe beim Client an, sondern nach einem zweiten Enter.
    Könntet Ihr euch das bitte anschaun.

    Client:

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <windows.h> 
    #include <winsock.h> 
    #include <conio.h> 
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <cstdio> 
    #include <vector>
    #include "format.h"
    
    using namespace std;
    
    #pragma comment(lib,"wsock32.lib")
    #pragma comment(lib,"advapi32.lib")
    
    // Startet Winsock und gibt einige Infos zur Version aus 
    // Starts winsock and dumps some infos about the version 
    int startWinsock() 
    { 
       int rc; 
       WSADATA wsaData; 
       rc=WSAStartup(MAKEWORD(2,0),&wsaData); 
    
       if(rc==SOCKET_ERROR) 
       { 
          printf("Error, exiting!\n"); 
          return rc; 
       }  
       //printf("System Status: %s\n",wsaData.szSystemStatus); 
       return 0; 
    } 
    
    // Sucht eine IP anhand eines Strings, der entweder die IP als String 
    // oder einen Hostname enthalten kann 
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr) 
    { 
       long rc; 
       unsigned long ip; 
    
       HOSTENT* he; 
    
       if(hostnameOrIp==NULL || addr==NULL) 
          return SOCKET_ERROR; 
       ip=inet_addr(hostnameOrIp); 
    
       if(ip!=INADDR_NONE)
       { 
          addr->sin_addr.s_addr=ip; 
          return 0; 
       } 
       else 
       { 
          he=gethostbyname(hostnameOrIp); 
          if(he==NULL) 
          { 
             return SOCKET_ERROR; 
          } 
          else 
          { 
             memcpy(&(addr->sin_addr),he->h_addr_list[0],4); 
          } 
          return 0; 
       } 
    } 
    
    int main(int argc, char* argv[]) 
    {    
        if(argc > 2)
        {
            char* HOST = argv[1];
            int PORT = atoi(argv[2]);
    
            SOCKET s; 
            SOCKADDR_IN addr; 
            char c; 
            char buf[1024]; 
            char inpBuf[1024]; 
            int inpBufPos=0; 
            fd_set fdSetRead; 
            TIMEVAL timeout; 
            int rc; 
    
            // start winsock 
            rc=startWinsock(); 
            if(rc==SOCKET_ERROR) 
            return 1; 
    
            // addr vorbereiten, hostname auflösen 
            // prepare addr, resolve hostname 
            memset(&addr,0,sizeof(SOCKADDR_IN)); 
            addr.sin_family=AF_INET; 
            addr.sin_port=htons(PORT); 
            rc=getAddrFromString(HOST, &addr); 
            if(rc==SOCKET_ERROR) 
            { 
                printf("Error: Cannot resolve Host %s\n", HOST); 
                return 1; 
            } 
    
            // socket erstellen 
            // create socket 
            s=socket(PF_INET,SOCK_STREAM,0); 
            if(s==INVALID_SOCKET) 
            { 
                printf("Error, cannot create socket: %d\n",WSAGetLastError()); 
                return 1; 
            } 
    
            // verbinden.. 
            // connect.. 
            printf("Connecting...\n"); 
            rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); 
            if(rc==SOCKET_ERROR) 
            { 
                printf("Error: connect failed: %d\n",WSAGetLastError()); 
                return 1; 
            }
    
            cout << endl;
    
            string str; //Eingabe String
    
            do
            {
    
                cout << "Eingabe:>";
    
                getline(cin, str);
    
                if(str == "exit")
                {
                    closesocket(s); 
                    WSACleanup(); 
                    return 0;
                }
    
                else if(str == "close")
                {
                    rc=send(s,str.c_str(),strlen(str.c_str()),0); 
                    if(rc==SOCKET_ERROR)
                    {
                        printf("Error: Sending to Server failed: %d\n",WSAGetLastError()); 
                    } 
                    closesocket(s); 
                    WSACleanup(); 
                    return 0;
                }
                //Sende Befehl...
                rc=send(s,str.c_str(),strlen(str.c_str()),0); 
                if(rc==SOCKET_ERROR)
                {
                    printf("Error: Sending to Server failed: %d\n",WSAGetLastError()); 
                } 
    
                // fd_set und timeout vorbereiten 
                FD_ZERO(&fdSetRead); 
                FD_SET(s,&fdSetRead); 
                timeout.tv_sec=0; 
                timeout.tv_usec=0; 
    
                // prüfen ob ein socket bereit ist, da timeout=0 kehrt die funktion 
                // sofort wieder zurück nach dem aufruf. 
                // achtung: das timeout auf 0 setzen oder als paremeter NULL mitgeben 
                // ist NICHT das gleiche. auf 0 gesetzt kehrt sofort zurück, während NULL blockt. 
                while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0) 
                { 
                    rc=recv(s,buf,1024,0); 
                    // server hat die verbindung beendet ? 
                    if(rc==0) 
                    { 
                        printf("Server closed connection!\n"); 
                        return 1; 
                    // fehler: beenden! 
                    } 
                    else if(rc==SOCKET_ERROR) 
                    { 
                        printf("Error: recv failed: %d\n",WSAGetLastError()); 
                        return 1; 
                    } 
                    // empfangene daten ausgeben 
                    buf[rc]='\0'; 
                    cout << buf << endl;
                } 
    
            }while(rc!=SOCKET_ERROR);//Ende do-while
    
            // aufräumen 
            // cleanup.. 
            closesocket(s); 
            WSACleanup(); 
            cout << "Client shutdown, press any key to exit" << endl;
            getch(); 
    
           }
           else    
           {
               cout << "Client HOST PORT" << endl;
           }
           return 0; 
    
    }
    

    Server:

    // max. Anzahl Clients 
    // Max. number of clients 
    #define MAX_CLIENTS 20
    
    // Der Standartwert für FD_SETSIZE ist 64, dieser kann aber verändert 
    // werden indem man FD_SETSIZE auf einen anderen Wert setzt bevor man 
    // winsock2.h includiert. 
    // FD_SETSIZE auf die max. Anzahl Clients setzten 
    #define FD_SETSIZE   MAX_CLIENTS 
    
    // includes... 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <windows.h> 
    #include <winsock.h> 
    #include <conio.h> 
    #include <string>
    #include <iostream>
    #include "convert.h"
    #include "registry.h"
    
    #pragma comment(lib, "wsock32.lib")
    #pragma comment(lib, "advapi32.lib")
    #pragma comment(lib,"user32.lib")
    
    using namespace std;
    
    // Stellt eine Verbindung mit einem Client dar 
    // Represents a connection with a Client 
    struct Connection 
    { 
       Connection() 
       { 
          used=false; 
          socket=INVALID_SOCKET; 
       } 
       void set(SOCKET s, SOCKADDR_IN addr) 
       { 
          this->socket=s; 
          this->addr=addr; 
          this->used=true; 
       } 
       void erase() 
       { 
          this->used=false; 
          this->socket=INVALID_SOCKET; 
       } 
       bool used;   // connection benutzt ? / connection slot used ? 
       SOCKET socket; // socket 
       SOCKADDR_IN addr; // client addr 
    }; 
    
    // clients 
    Connection clients[MAX_CLIENTS]; 
    
    // Sucht den nächsten freien Platz im clients Array 
    // -1 = kein platz frei 
    // Searches the next free slot in the clients array 
    // -1 = no free slot 
    int getFreeClientSlot() 
    { 
       for(int i=0;i<MAX_CLIENTS;i++) 
       { 
          if(clients[i].used==false) 
             return i; 
       } 
       return -1; 
    } 
    
    // Startet Winsock und gibt einige Infos zur Version aus 
    // Starts winsock and dumps some infos about the version 
    int startWinsock() 
    { 
       int rc; 
       WSADATA wsaData; 
       rc=WSAStartup(MAKEWORD(2,0),&wsaData); 
    
       if(rc==SOCKET_ERROR) { 
          printf("Error, exiting!\n"); 
          return rc; 
       }   
       printf("System Status: %s\n",wsaData.szSystemStatus); 
       return 0; 
    } 
    
    #define MAX_LINE_LENGTH 1024
    
    BOOL ProcessCommandLine(char * pcCommandLine, SOCKET s)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        SECURITY_ATTRIBUTES sa;
        HANDLE hReadPipe, hWritePipe;
        DWORD dwWaitResult = WAIT_TIMEOUT, dwBytesRead, dwExitCode, dwSizeLow, dwSizeHigh, dwError;
        char cReadLine[MAX_LINE_LENGTH];
        BOOL bDoRead = TRUE, bOK = TRUE;
        MSG AppMsg;
    
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
    
        //Pipes erzeugen
        sa.nLength=sizeof(sa);
        sa.bInheritHandle=TRUE;
        sa.lpSecurityDescriptor=NULL;
        bOK = CreatePipe(&hReadPipe, &hWritePipe, &sa, 1048576);
        if(!bOK)
        {
            //FEHLER
            dwError = GetLastError();
            bOK = FALSE;
            goto PROCESS_END_NOPIPE;
        }
    
        //Pipes eintragen
        si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        si.hStdOutput = hWritePipe;                        //Schreib-Ende der Pipe an Prozess übergeben
        si.hStdError = hWritePipe;                        //Schreib-Ende der Pipe an Prozess übergeben
        si.wShowWindow = SW_SHOWMINNOACTIVE;
    
        //Prozess starten
        bOK = CreateProcess(NULL,
                            pcCommandLine,
                            NULL,
                            NULL,
                            TRUE,
                            NORMAL_PRIORITY_CLASS,
                            NULL,
                            NULL,
                            &si,
                            &pi);
    
        if(!bOK)
        {
            //FEHLER
            dwError = GetLastError();
            goto PROCESS_END_NOPROC;
        }
    
        //Auf Ende warten und Messages lesen
        while(dwWaitResult != WAIT_OBJECT_0)
        {
            dwWaitResult = WaitForSingleObject(pi.hProcess, 10);
            while(dwSizeLow = GetFileSize(hReadPipe, &dwSizeHigh))
            {
                ZeroMemory(cReadLine, MAX_LINE_LENGTH);
                //Aus dem Leseende der Pipe die Progzessausgaben lesen
                if(bDoRead = ReadFile(hReadPipe, cReadLine, MAX_LINE_LENGTH - 1, &dwBytesRead, NULL))
                {
                    if(dwBytesRead)
                    {
                        //**** hier Programmausgabe verarbeiten (z.B. send) *******
                        send(s, cReadLine, strlen(cReadLine), 0);
                    }
                }
                else
                {
                    bOK = FALSE;
                    dwError = GetLastError();
                }
            }
            //Applikations-Messagequeue verarbeiten
            if(PeekMessage(&AppMsg, 0, 0, 0, PM_NOREMOVE))
            {
                GetMessage(&AppMsg, 0, 0, 0);
                TranslateMessage(&AppMsg);
                DispatchMessage(&AppMsg);
            }
        }
    
        if(bOK)
        {
            bOK = GetExitCodeProcess(pi.hProcess, &dwExitCode);
            if(bOK)
            {
                if(dwExitCode != 0)
                {
                    //Prozess kehrt mit Ergebnis != 0 zurück
                    bOK = FALSE;
                }
            }
            else
            {
                //FEHLER im GetExitCodeProcess
                dwError = GetLastError();
                bOK = FALSE;
            }
        }
    
        //Close handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    
    PROCESS_END_NOPROC:
        CloseHandle(hWritePipe);
        CloseHandle(hReadPipe);
    
    PROCESS_END_NOPIPE:
        return bOK;
    }
    
    int main(int argc, char* argv[]) 
    { 
        if(argc > 1)
        {
            //Startet auf dem übergebenem PORT
            int PORT = atoi(argv[1]);
    
           // SOCKET welcher neue Verbindungen annimmt 
           // SOCKET which accepts new connections 
           SOCKET acceptSocket; 
           SOCKADDR_IN addr; 
           int rc,addrsize=sizeof(SOCKADDR_IN); 
           unsigned int i,j; 
           // fd_set 
           fd_set fdSetRead; 
           // timout für select() / timeout for select() 
           timeval selectTimeout; 
           // temporär benutz für neue verbindungen 
           // temporary used for new connections 
           Connection newConnection; 
           // buffer 
           char buf[1024]; 
    
           // clients array leeren / clear clients array 
           memset(clients,0x0,sizeof(Connection)*MAX_CLIENTS); 
    
           // start winsock 
           rc=startWinsock(); 
           if(rc==SOCKET_ERROR) 
              return 1; 
    
           // socket erstellen / create socket 
           acceptSocket=socket(PF_INET,SOCK_STREAM,0); 
           if(acceptSocket==INVALID_SOCKET) 
           { 
              printf("Error, cannot create socket: %d\n",WSAGetLastError()); 
              return 1; 
           } 
    
           // sockt an port 1234 binden / bind socket to port 1234 
           memset(&addr,0,sizeof(SOCKADDR_IN)); 
           addr.sin_family=AF_INET; 
           addr.sin_port=htons(PORT); 
           addr.sin_addr.s_addr=INADDR_ANY; 
           rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); 
           if(rc==SOCKET_ERROR) 
           { 
              printf("Error, bind() failed: %d\n",WSAGetLastError()); 
              return 1; 
           } 
    
           // auf verbindungen warten / listen for connections 
           rc=listen(acceptSocket,10); 
           if(rc==SOCKET_ERROR) 
           { 
              printf("Error,listen() failed: %d\n",WSAGetLastError()); 
              return 1; 
           } 
    
           // The parameter readfds identifies the sockets that are to be checked for readability. 
           // If the socket is currently in the listen state, it will be marked as readable if an 
           // incoming connection request has been received such that an accept is guaranteed to 
           // complete without blocking. 
    
           while(1) 
           { 
    
              // fd_set leeren / clear fd_set 
              FD_ZERO(&fdSetRead); 
    
              // den socket welcher verbindungen annimmt hinzufügen 
              // add the SOCKET which accepts new connections 
    
              FD_SET(acceptSocket,&fdSetRead); 
              // alle clients hinzufügen 
              // add all clients 
              for(i=0;i<MAX_CLIENTS;i++) 
              { 
                 if(clients[i].used) 
                    FD_SET(clients[i].socket,&fdSetRead); 
              } 
    
              // warten bis irgend ein socket bereit ist, wenn timout NULL ist kehrt select() 
              // erst zurück wenn ein socket bereit ist, select() blockt also in diesem falle 
              // wait until any socket is ready (timeout = NULL, block until one socket is ready) 
              rc=select(0,&fdSetRead,NULL,NULL,NULL); 
    
              // abbrechen bei einem fehler 
              // break on error 
              if(rc<1) 
                 break; 
    
              printf("select() returned %d ready sockets\n",rc); 
    
              for(i=0;i<fdSetRead.fd_count;i++) 
              { 
    
                 // acceptSocket ? 
                 if(fdSetRead.fd_array[i]==acceptSocket) 
                 { 
                    // verbindung annehmen / accept new connection 
                    newConnection.socket=accept(acceptSocket,(SOCKADDR*)&newConnection.addr,&addrsize); 
                    rc=getFreeClientSlot(); 
                    if(rc==-1) 
                    { 
                       printf("Cannot accept new clients\n"); 
                       continue; 
                    } 
                    // zu den clients hinzufügen 
                    // add to clients 
                    clients[rc]=newConnection; 
                    clients[rc].used=true; 
                    printf("New Client accepted from %s\n",inet_ntoa(newConnection.addr.sin_addr)); 
                    continue; 
                 } 
    
                 // ein client ? 
                 // a client ? 
                 for(j=0;j<MAX_CLIENTS;j++) 
                 { 
                    if(!clients[j].used) 
                       continue; 
    
                    if(clients[j].socket==fdSetRead.fd_array[i]) 
                    { 
                       rc=recv(clients[j].socket,buf,1023,0); 
                       buf[rc]='\0'; 
                       // rc==0 => client hat die verbindung beendet 
                       if(rc==0) { 
                          printf("Client %d (%s): closed connection\n",j,inet_ntoa(clients[j].addr.sin_addr)); 
                          closesocket(clients[j].socket); 
                          clients[j].erase(); 
                          continue; 
                       // rc==SOCKET_ERROR => fehler, verbindung beenden! 
                       } 
                       else if(rc==SOCKET_ERROR) 
                       { 
                          printf("Client %d (%s): Error %d\n",j,inet_ntoa(clients[j].addr.sin_addr),WSAGetLastError()); 
                          printf("Client %d (%s): Server aborts connection\n",j,inet_ntoa(clients[j].addr.sin_addr)); 
                          closesocket(clients[j].socket); 
                          clients[j].erase(); 
                          continue; 
                       // daten empfangen und an alle clients senden 
                       } 
                       else 
                       { 
                           printf("Client %d (%s): Befehl: '%s' \n",j,inet_ntoa(clients[j].addr.sin_addr),buf); 
                          //sendToAllClients(buf); 
    
                          string command = buf;
                          if(command.find(' ') != string::npos)
                          {                          
                              int pos = command.find(' ');   
                              int lang = command.length();
                                string task = command.substr(0,pos);
                              string para = command.substr(pos+1,lang);
    
                              string str;
                              str += '"';
                              str += reg.xmd_GetValue("bin");
                              str += "\\";
                              str += task;
                              str += ".exe";
                              str += '"';
                              str += " " + para;
    
                              cout << "Erfolgreich: " << ProcessCommandLine(cvt.StringToChar(str), clients[j].socket) << endl;
                          }
    
                          else
                          {                            
                             if(command == "close")                        
                             {
                                 //rc=send(clients[i].socket,msg,strlen(msg),0); 
                                 //  rc=send(clients[j].socket,task.c_str(),strlen(task.c_str()),0); 
                                 closesocket(acceptSocket); 
                                 WSACleanup();
                             }                         
                             cout << "Erfolgreich: " << ProcessCommandLine(cvt.StringToChar(command), clients[j].socket) << endl;
                          }          
    
                       } 
                    } 
                 } 
              }
    
              cout << "-----------------------------------" << endl;
           }//Ende while
    
           // aufräumen 
           closesocket(acceptSocket); 
           WSACleanup();        
        }
        else 
        {
            cout << "server PORT" << endl;
        }
    
        return 0;   
    }
    


  • kernel64 schrieb:

    Könntet Ihr euch das bitte anschaun.

    versuch den fehler weiter einzugrenzen (bau z.b. überall debug-ausgaben ein)...



  • Habe im mittleren Teil vom Client folgendes eingefügt:

    //Eingabe des Befehl
    getline(cin, str);
    
    rc=send(s,str.c_str(),strlen(str.c_str()),0); 
    			if(rc==SOCKET_ERROR)
    			{
    				printf("Error: Sending to Server failed: %d\n",WSAGetLastError()); 
    			} 
    
    		cout << "vor While..." << endl;
    
    			// fd_set und timeout vorbereiten 
    			FD_ZERO(&fdSetRead); 
    			FD_SET(s,&fdSetRead); 
    			timeout.tv_sec=0; 
    			timeout.tv_usec=0; 
    
    			// prüfen ob ein socket bereit ist, da timeout=0 kehrt die funktion 
    			// sofort wieder zurück nach dem aufruf. 
    			// achtung: das timeout auf 0 setzen oder als paremeter NULL mitgeben 
    			// ist NICHT das gleiche. auf 0 gesetzt kehrt sofort zurück, während NULL blockt. 
    			while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0) 
    			{
    			cout << "in while..." << endl;
    
    				rc=recv(s,buf,1024,0); 
    				// server hat die verbindung beendet ? 
    				if(rc==0) 
    				{ 
    					printf("Server closed connection!\n"); 
    					return 1; 
    				// fehler: beenden! 
    				} 
    				else if(rc==SOCKET_ERROR) 
    				{ 
    					printf("Error: recv failed: %d\n",WSAGetLastError()); 
    					return 1; 
    				} 
    			cout << "empfange..." << endl;
    				// empfangene daten ausgeben 
    				buf[rc]='\0'; 
    				cout << buf << endl;
    			} 
    
    		cout << "nach While()" << endl;
    

    Folgendes passiert wenn ich test eingebe: (test ist eine test.exe mit einer Ausgabe)

    Eingabe: test //test dann Enter
    vor While...
    nach While()
    //keine Ausgabe

    Eingabe: //hier nichts eingegeben und dann Enter gedrückt
    vor While...
    in While...
    empfange...
    ....//Hier kommt die Ausgabe von test
    nach while()

    Wie man sieht wird bei der ersten eingabe die while schleife nicht abgearbeitet.
    Woran kann das liegen ist der server fehlerhaft??
    Bitte um Hilfe!



  • Hi

    Hab ehrlich gesagt keine Lust, deinen kompletten Code durchzusehen (bin aber drübergeflogen). Und ein Tip: Poste nicht zuviel Code (das da ist definitiv zu viel! Das treibt nämlich potenziellen Helfern die Lust am helfen aus!
    <- Nicht böse gemeint 😉

    Zu deinem Problem:
    Wenn man die Ausgabe richtig deutet, wird in deinem Fall bei der Eingabe von "test" folgende Zeile

    while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0)
    

    abgearbeitet und select gibt irgendwas kleiner gleich 0 zurück. Logisch, oder? Immerhin geht er gar nicht erst in die Schleife rein. Also finde am besten erstmal raus, warum select <= 0 zurückgibt. Gib für diesen Fall z.B. mal "rc" aus.



  • Hab folgendes ergänzt:

    //vor der schleife
    cout << "vor While..." << endl;
    cout << "rc:" << rc << endl;
    
    while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0) 
    {
    cout << "in while..." << endl;
    				cout << "rc:" << rc << endl;
    
    //...
    
    }
    cout << "nach While()" << endl;
    			cout << "rc:" << rc << endl;
    

    Folgendes wird ausgegeben wenn ich ein Befehl eingebe:

    Eingabe: test //Befehl
    vor While...
    rc:4
    nach While()
    rc:0

    Eingabe: //hier nichts eingegeben und dann Enter gedrückt
    vor While...
    rc:0
    in while...
    rc:1
    empfange...
    ...//Hier kommt die Ausgabe von test
    nach While()
    rc:0



  • Das ist doch schonmal was! Aber könntest ja auch mal selber versuchen, deine Ausgaben zu interpretieren :p

    Naja, also:
    Bei dieser Ausgabe: "cout << "rc:" << rc << endl;" ist rc ja der Rückgabewert von send(...). Nachschauen-> send gibt die Anzahl von Bytes zurück, die gesendet wurden. Also wurden erfolgreich die 4 Bytes ("test") gesendet! Das funktioniert also!
    Der Eintritt in die While-Schleife scheitert und select hat 0 zurückgegeben. Bedeutet, dass nix angekommen ist, in dieser kurzen Zeit.
    ⚠
    Bei der nächsten Eingabe (bei dir "" <-Nix) ruft er wieder select auf und siehe da ➡ Es wartet ein Paket.
    Daraus könnte man schlussfolgern, dass das erste select so schnell aufgerufen wurde (direkt nach dem senden), dass das Paket in der kurzen Zeit noch gar nicht angekommen ist!
    Ist das nicht eine Erkenntnis 😕 ? Lass dem Paket also ein bisschen Zeit, dann müsste es funktionieren, scheint ja sonst alles korrekt zu sein.

    Mit freundlichen Grüßen,
    Badestrand



  • Das was du meinst hab ich auch die ganze Zeit gedacht, dass beim Client die Daten viel zu früh erwartet werden. Hab den Client mal mit dem debugger gestartet also mit F10 und gabs keine Probleme, da hier alles Schritt für Schritt abgearbeitet wird, deshalb sind alle Daten angekommen.

    Lass dem Paket also ein bisschen Zeit, dann müsste es funktionieren, scheint ja sonst alles korrekt zu sein.
    

    Also ich werde ein Sleep(1000) einbauen, mal sehn wie es dann läuft.
    Danke nochmals für die Erkenntnis.

    [Edit] Es funktioniert danke 🙂 habe für Sleep(500) eingesetzt müsste ausreichen.
    Wie sieht es mit dem Buffer aus, der dritte parameter bei recv() send()?

    recv(s,buf,1024,0);
    

    Soll da 1024 oder 1023 stehn?



  • Bin froh, dass es doch noch geklappt hat!

    kernel64 schrieb:

    Wie sieht es mit dem Buffer aus, der dritte parameter bei recv() send()?

    recv(s,buf,1024,0);
    

    Soll da 1024 oder 1023 stehn?

    Da dein Buffer 1024 Byte groß ist, stimmt das schon mit der 1024. Da du allerdings das letzte Zeichen auf '\0' setzt, mach lieber 1023. Wenn du nämlich 1024 Bytes an Daten empfängst (Rückgabewert rc=1024), dann schreibst du mit "Buf[rc]='\0';" in das 1025-ste Byte. Das wär zuviel.

    Mfg,
    badestrand



  • Vielen vielen Dank, endlich klappts 🙂
    Hatte immer ein fehler wenn ich den client beendet habe:

    'buf' Stack corrupted

    Wahrscheinlich wegen denn 1024



  • Noch ne kleine Frage nebenbei, wie soll ich folgendes senden:

    string pc;
    		pc += "host:";
    		pc += ComputerName();
    		pc += "\n";
    

    Habe es so gemacht:

    send(s, pc.c_str(), pc.length(), 0);
    

    Wie würdest du das machen?



  • kernel64 schrieb:

    Habe es so gemacht:

    send(s, pc.c_str(), pc.length(), 0);
    

    Wie würdest du das machen?

    Kannste doch so machen, allerdings kannste zur Verkettung auch das machen:

    string pc(string("host:") + string(ComputerName()) + string("\n"));
    


  • Aber wie sieht das Empfangen auf der Gegenseite aus, also welche größe soll bei recv() dann verwendet werden? Die göße von pc ist ja dynamisch!



  • Du kannst ja einfach auch einen Puffer von 1024 Bytes nehmen. Wenn recv(...) dann einen Wert von 1024 zurückgibt, besteht eine gute Chance, dass noch mehr Bytes warten. Es werden dann ja schließlich nicht mehr als 1024 in deinen Puffer geschrieben!
    Also dann Puffer vergrößern ➡ Dynamischer Puffer mit new[] und delete[] oder malloc, realloc(!) und free anlegen.

    - Puffer anlegen mit 1024 Bytes Größe
    - recv mit 1024 aufrufen
    - Wenn recv 1024 zurückgibt, dann Puffer vergrößern und immer wieder recv mit wieder 1024 und richtiger Pufferposition aufrufen, bis recv<1024
    - Dann letztes Byte auf '\0' setzen und ausgeben
    

Anmelden zum Antworten