Sockets: mehrere clients. das wäre sehr nett wenn ihr mir helfen könntet büdde



  • ich habe den beispielcode von http://www.c-worker.ch/tuts/select.php genommen
    da geht es um einen chat-server und -client:

    server:

    #pragma comment( lib, "ws2_32.lib" )
    
    #include <windows.h>
    #include <winsock2.h> // bei manchan compilern muss man nur windows.h includieren (zB VC++)
    #include <stdio.h>
    
    #define MAX_CLIENTS 10
    
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    int main()
    {
      long rc;
      SOCKET acceptSocket;
      //SOCKET connectedSocket;
      SOCKADDR_IN addr;
      char buf[256];
      char buf2[300];
      // zusätzliche Variabeln
      FD_SET fdSet;
      SOCKET clients[MAX_CLIENTS];
      int i;
    
      // Winsock starten
      rc=startWinsock();
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
    
      // Socket erstellen
      acceptSocket=socket(AF_INET,SOCK_STREAM,0);
      if(acceptSocket==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
    
      // Socket binden
      memset(&addr,0,sizeof(SOCKADDR_IN));
      addr.sin_family=AF_INET;
      addr.sin_port=htons(12345);
      addr.sin_addr.s_addr=INADDR_ANY; // gewisse compiler brauchen hier ADDR_ANY
      rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket an port 12345 gebunden\n");
      }
    
      // In den listen Modus
      rc=listen(acceptSocket,10);
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("acceptSocket ist im listen Modus....\n");
      }
    
      for(i=0;i<MAX_CLIENTS;i++)
      {
        clients[i]=INVALID_SOCKET;
      }
    
      while(1)
      {
        FD_ZERO(&fdSet); // Inhalt leeren
        FD_SET(acceptSocket,&fdSet); // Den Socket der verbindungen annimmt hinzufügen
    
        // alle gültigen client sockets hinzufügen (nur die die nicht INVALID_SOCKET sind)
        for(i=0;i<MAX_CLIENTS;i++)
        {
          if(clients[i]!=INVALID_SOCKET)
          {
            FD_SET(clients[i],&fdSet);
          }
        }
    
        rc=select(0,&fdSet,NULL,NULL,NULL); // nicht vergessen den ersten parameter bei anderen betriebssystem anzugeben
        if(rc==SOCKET_ERROR)
        {
          printf("Fehler: select, fehler code: %s\n",WSAGetLastError());
          return 1;
        }
    
        // acceptSocket is im fd_set? => verbindung annehmen (sofern es platz hat)
        if(FD_ISSET(acceptSocket,&fdSet)) {
          // einen freien platz für den neuen client suchen, und die verbingung annehmen
          for(i=0;i<MAX_CLIENTS;i++)
          {
            if(clients[i]==INVALID_SOCKET)
            {
              clients[i]=accept(acceptSocket,NULL,NULL);
              printf("Neuen Client angenommen (%d)\n",i);
              break;
            }
          }
        }
    
        // prüfen wlecher client sockets im fd_set sind
        for(i=0;i<MAX_CLIENTS;i++)
        {
          if(clients[i]==INVALID_SOCKET)
          {
            continue; // ungültiger socket, d.h. kein verbunder client an dieser position im array
          }
          if(FD_ISSET(clients[i],&fdSet))
          {
            rc=recv(clients[i],buf,256,0);
            // prüfen ob die verbindung geschlossen wurde oder ein fehler auftrat
            if(rc==0 || rc==SOCKET_ERROR)
            {
              printf("Client %d hat die Verbindung geschlossen\n",i);
              closesocket(clients[i]); // socket schliessen         
              clients[i]=INVALID_SOCKET; // seinen platz wieder freigeben
            }
            else
            {
              buf[rc]='\0';
              // daten ausgeben und eine antwort senden
              printf("Client %d hat folgendes gesandt: %s\n",i,buf);
              // antwort senden
              sprintf(buf2,"Du mich auch %s\n",buf);
              send(clients[i],buf2,(int)strlen(buf2),0);
    		}
    	  }
    	}
      }
    }
    

    client:

    #include <windows.h>
    #include <winsock2.h>
    #include <stdio.h>
    
    //Prototypen
    int startWinsock(void);
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr);
    
    int main(int argc, char** argv)
    {
      long rc;
      SOCKET s;
      SOCKADDR_IN addr;
      char buf[256];
    
      if(argc<2)
      {
        printf("Usage: sock <hostname oder ip des servers>\n");
        return 1;
      }
    
      // Winsock starten
      rc=startWinsock();
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
    
      // Socket erstellen
      s=socket(AF_INET,SOCK_STREAM,0);
      if(s==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
    
      // Verbinden
      memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
      addr.sin_family=AF_INET;
      addr.sin_port=htons(12345); // wir verwenden mal port 12345
      rc=getAddrFromString(argv[1],&addr);
      if(rc==SOCKET_ERROR)
      {
        printf("IP für %s konnte nicht aufgeloest werden\n", argv[1]);
        return 1;
      }
      else
      {
        printf("IP aufgeloest!\n");
      }
    
      rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Verbunden mit 127.0.0.1..\n");
      }
    
      // Daten austauschen
      while(rc!=SOCKET_ERROR)
      {
        printf("\nZeichenfolge eingeben [max 256]: ");
        gets(buf);
        send(s,buf,strlen(buf),0);
        rc=recv(s,buf,256,0);
        if(rc==0)
        {
          printf("Server hat die Verbindung getrennt..\n");
          break;
        }
        if(rc==SOCKET_ERROR)
        {
          printf("Fehler: recv, fehler code: %d\n",WSAGetLastError());
          break;
        }
        buf[rc]='\0';
        printf("\nServer antwortet: %s\n",buf);
      }
      closesocket(s);
      WSACleanup();
      return 0;
    }
    
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr)
    
    {
      long rc;
      unsigned long ip;
      HOSTENT* he;
    
      /* Parameter prüfen */
      if(hostnameOrIp==NULL || addr==NULL)
        return SOCKET_ERROR;
    
      /* eine IP in hostnameOrIp ? */
      ip=inet_addr(hostnameOrIp);
    
      /* bei einem fehler liefert inet_addr den Rückgabewert INADDR_NONE */
      if(ip!=INADDR_NONE)
      {
        addr->sin_addr.s_addr=ip;
        return 0;
      }
      else
      {
        /* Hostname in hostnameOrIp auflösen */
        he=gethostbyname(hostnameOrIp);
        if(he==NULL)
        {
          return SOCKET_ERROR;
        }
        else
        {
          /*die 4 Bytes der IP von he nach addr kopieren */
          memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
        }
        return 0;
    
      }
    }
    

    meine frage ist: ist es möglich bei dem server für jeden clienten ein neues fenster zu öffnen damit man den chatt voll ausnutzen kann?



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten