icf finde den Fehler nicht, variable wird nur vorübergehend deklariert



  • hu

    #include <stdio.h>
    #include <iostream>
    #pragma comment( lib, "ws2_32.lib" )
    #include <conio.h>
    #include <winsock2.h>
    #include <windows.h>
    #include <process.h>
    #include <cstdlib>
    //#include <afxwin.h> //für thread scheisse
    #include "Spieler.h"
    
    DWORD WINAPI server( LPVOID lpParam );
    DWORD WINAPI client( LPVOID lpParam );
    int startWinsock(void);
    
    using namespace std;
    /*
    Das Konzept
    
    1 Server
    2 Sockets
    
      Der Server verteilt die Koordinaten Informationen (x,y) auf alle Clienten.
      1 Socket "horcht" auf Daten, der andere Socket sendet Daten (Nutzereingaben)
    
    */
    SOCKET s;
    Spieler spieler[2];
    int spielernummer;
    
    int poplast(char *zkette)
    {
    	//ersten Wert der Zeichenkette bis '|' zeichen abschneiden und zurück geben
    	int wert=0;
    	char tmpwert[3]="";
    	int laenge = strlen(zkette);
    	zkette+=laenge;	//zum letzten zeichen springen
    
    	while(*zkette != ',' && laenge > 0)
    	{
    		strcat(tmpwert, zkette);
    		--zkette;
    	}
    
    	*zkette='\0';
    
    	return atoi(tmpwert);
    }
    
    int main()
    {
    	char kette[]=",1,2,3,40";
    
    	while(*kette)
    	{
    		cout<<poplast(kette)<<endl;
    	}
    	HANDLE hThread[2];
    	DWORD dwThrdParam = 1; 
    	char eingabe;
    	int choose;
    	int x=0 ,y=0;
    
    	//up=H, down=P, left=K, right=M
    
    	cout<<"Server (1): "; cin>>choose;
    
    	if(choose==1)
    	{
    		hThread[0]=CreateThread( 
    		0,								// default security attributes 
    		0,								// use default stack size  
    		server,							// thread function 
    		0,								// argument to thread function 
    		0,								// use default creation flags 
    		&dwThrdParam);					// returns the thread identifier 	return 0;
    	}
    
    		hThread[0]=CreateThread( 
    		0,								// default security attributes 
    		0,								// use default stack size  
    		client,							// thread function 
    		0,								// argument to thread function 
    		0,								// use default creation flags 
    		&dwThrdParam);					// returns the thread identifier 	return 0;
    
      char posx[3]="";
      char werte[9]="";	//,x,y
    	while(true)
    	{
    		char tmp[2];
    		Spieler tmpgamer;
    
    		eingabe=getch();
    		if(eingabe=='w' && y > 0  )	y-=1;
    		if(eingabe=='s' && y < 30 )	y+=1;
    		if(eingabe=='a' && x > 0  )	x-=1;
    		if(eingabe=='d' && x < 80 )	x+=1;
    
    		tmpgamer.setX(x);
    		tmpgamer.setY(y);
    
    		send(s, (char *) &tmpgamer , sizeof(tmpgamer) , 0);	//,nr,x,y senden
    	}
    
    	return 0;
    }
    
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
    }
    
    DWORD WINAPI server( LPVOID lpParam ) 
    { 
    #define MAX_CLIENTS 10
    //	Spieler spieler[MAX_CLIENTS];
    
      int ePort;
      long rc;
      SOCKET acceptSocket;
      //SOCKET connectedSocket;
      SOCKADDR_IN addr;
      char posx[3];
      char posy[3];
      char koordinaten[MAX_CLIENTS][9];
      char koordinaten_backup[MAX_CLIENTS][9];
    
      // zusätzliche Variabeln
      FD_SET fdSet;
      SOCKET clients[MAX_CLIENTS];
      int i;
      ePort=2;
      // 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(2);
      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 %d gebunden\n",ePort);
    
      // 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)
            {
    		  spieler[i].setNr(0); //hat irgendwie keine Auswrikungen
              clients[i]=accept(acceptSocket,NULL,NULL);
              printf("Neuen Client angenommen (%d)\n",i);
    
              break;
            }
          }
        }
    	//spieler[0].setNr(0);
    
        // 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] , (char *) &spieler[i], sizeof(spieler[i]), 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
            {
    			//cout<<"Spieler ("<<spieler[i].getNr()<<") [x: "<<spieler[i].getX()
    			//	<<" y: "<<spieler[i].getY()<<']'<<endl;
    
    		// spieler[0].setNr(0);
    		// spieler[1].setNr(1);
    		  for(int x=0;x<MAX_CLIENTS;++x)
              {
    			if(!(clients[x]==SOCKET_ERROR))
                {
    				for(int alle=0;alle<MAX_CLIENTS;++alle)
    				{
    					if(!(clients[alle]==SOCKET_ERROR) )
    					{	
    						//spieler[x].setNr(nr);	//ohne dem funxt es nicht, komisch
    
    						//cout<<x<<endl;
    						//send(clients[x], (char *) &spieler[alle], sizeof(spieler[alle]), 0);
    						cout<<"Nummer: "<<spieler[0].getNr()<<endl;
    					}
    				}	
    			}
              }
    		  cout<<"_______________________________________\n";
    		}
    	  }
    	}
      }
    
        return 0; 
    }
    
    DWORD WINAPI client( LPVOID lpParam ) 
    {
      Spieler tmpspieler;
      short int rc;
      SOCKADDR_IN addr;
      FD_SET fdset;
    
      rc=startWinsock();
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
      }else
      {
        printf("Winsock gestartet!\n");
      }
      s=socket(2,SOCK_STREAM,0);
      if(s==INVALID_SOCKET)    printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
      else					   printf("Socket erstellt!\n");
    
      memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten 
      addr.sin_family=AF_INET;
      addr.sin_port=htons(2); // wir verwenden mal port 2
      addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener
      rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
      if(rc==SOCKET_ERROR)    printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
      else					  printf("Verbunden mit 127.0.0.1..\n");
    
      FD_ZERO(&fdset);
      FD_SET(s,&fdset);
      //select(0,&fdset,NULL,NULL,NULL);
      do
      {
    	 rc=recv(s, (char *) &tmpspieler, sizeof(tmpspieler), 0);
    	 system("cls");
    
    	 //cout<<"Nr.: "<<tmpspieler.getNr()<<endl;
    	 spieler[tmpspieler.getNr()].setX(tmpspieler.getX());
    	 spieler[tmpspieler.getNr()].setY(tmpspieler.getY());
    	 spieler[tmpspieler.getNr()].setNr(tmpspieler.getNr());
         if(rc!=0)
         {
    		//system("cls");
    
    		for(int i=0; i< 2; ++i)
    		{	
    			if(spieler[i].getNr()!=-1)
    			{
    			/*
    				cout<<"Nr.: "<<spieler[i].getNr()
    					<<" x: "<<spieler[i].getX()
    					<<"  y: "<<spieler[i].getY()<<endl;
    			*/
    				gotoxy(spieler[i].getX(), spieler[i].getY());
    
    				if(i==0)	cout<<'x';
    				if(i==1)	cout<<'y';
    			}
    		}
    	 }
    	 select(0,&fdset,NULL,NULL,NULL);
    
      }while(true);
    
      closesocket(s);
    
    	return 0;
    }
    

    Die Klasse Spieler:

    #ifndef SPIELER_H
    #define SPIELER_H
    
    void gotoxy(short x, short y)
    {
    	HANDLE hstdout;
    	COORD pos;
    	pos.X=x;
    	pos.Y=y;
    	hstdout=GetStdHandle(STD_OUTPUT_HANDLE);
    	SetConsoleCursorPosition(hstdout, pos);
    
    }
    
    class Spieler
    {
    	public:
    		Spieler()
    		:_x(0), _y(0), _nummer(-1)
    		{}
    		void setX(short x){	_x=x;	}
    		void setY(short y){	_y=y;	}
    		short getX(){	return _x;	}
    		short getY(){	return _y;	}
    		void setNr(int nummer){		_nummer=nummer;	}
    		int getNr(){	return _nummer;	}
    	private:
    		short _x, _y, _nummer, _hm;
    };
    
    #endif //SPIELER_H
    

    Hier wird der Spieler mit einer Nummer versehen die erst einmal fortlaufend ist. Die Nummer wird beim Verbinden auf dem Server festgelegt.

    if(clients[i]==INVALID_SOCKET)
            {
    		  spieler[i].setNr(0); //hier wird die Nummer auf "0" gesetzt          
    clients[i]=accept(acceptSocket,NULL,NULL);
              printf("Neuen Client angenommen (%d)\n",i);
    
              break;
            }
    

    Da es mehrere Spieler geben kann, wird an jeden Spieler die Koordnaten der anderen Spieler gesendet einschließlich der Nummer.
    Die Nummer ist aber komischerweise an der Stelle immer "-1", gemäß dem Konstruktor...das darf aber nicht sein, da jeder SPieler beim verbinden eine Nummer zugewiesen bekommt.
    Warum ist die Nummer bei diesem Quellcode Teil "-1"?

    for(int x=0;x<MAX_CLIENTS;++x)
              {
    			if(!(clients[x]==SOCKET_ERROR))
                {
    				for(int alle=0;alle<MAX_CLIENTS;++alle)
    				{
    					if(!(clients[alle]==SOCKET_ERROR) )
    					{	
    												cout<<"Nummer: "<<spieler[0].getNr()<<endl; //hier ist die Nummer "-1", es müsste aber eigentlich "0" ausgegeben werden
    					}
    				}	
    			}
              }
    		  cout<<"_______________________________________\n";
    

    Helft mir bitte.

    cu



  • Du kannst doch nicht erwarten, dass sich hier jeder durch deinen kompletten Source gräbt. Spezifiziere dein Problem doch ein bisschen...



  • cout<<"Nummer: "<<spieler[0].getNr()<<endl; //hier ist die Nummer "-1", es müsste aber eigentlich "0" ausgegeben werden
    

    ist das beabsichtigt, dass du hier immer auf spieler[0] zugreifst?



  • hi

    Ja, ist beabsichtigt.

    Beispiel:

    Der erste Spieler connectet auf den Server. Er bekommt dabei mit setNr(..) die Nummer 0 zugewiesen.
    Dann will ich von dem ersten Spieler die Nummer wieder ausgeben und es kommt eine -1 heraus statt einer 0....und das verstehe ich nicht.

    cu


Anmelden zum Antworten