Gå til innhold

Har rekkefølge på deklarasjon noe å si?


Anbefalte innlegg

Postet originalt i hjelpetråden, men håpte å kanskje få litt flere views og muligens raskere svar. :) Har ikke kunnet finne noe lignende på google.

 

Jeg har en header fil som brukes til sockets vha. SFML.

 

Dersom jeg endrer rekkefølgen på deklerasjonene, så slutter alt å fungere. Hvorfor?

 

Versjon 1 fungerer, versjon 2 kjører uten feil men kan ikke sende eller motta pakker, versjon 3 gir en Memory Access reading violation.

 

Det eneste jeg gjør er å flytte på linja:

sf::SocketTCP Client;

 

Koden er veldig rotete beklager det, fant denne feilen når jeg skulle rydde i koden, og endra på rekkefølgen i fila og fjernet noen variabler jeg kun brukte for å finne ut av ting, og plutselig fungerte ingenting lengre.

 

Har også inkludert en versjon 4, som er min "oppryddede" versjon av koden, dersom det skulle være interessant å se hva jeg faktisk bruker i filen.

 

Fungerer:

 

 

//============================================================================= 
#ifndef _CCLIENT_H_ 
   #define _CCLIENT_H_ 

#include <SFML/Network.hpp> 
#include <string> 
#include "CEntity.h" 

//============================================================================= 
class CClient{ 
   public: 
     struct Playern 
{ 
  int      PID; 
  int      X; 
   int      Y; 
  int      Dead; 
}; 
     // Packet content 
  int packetID; 
  int entityID; 
  int playerID; 
  int command; 
  // --------------- 
  sf::SelectorTCP selector; 
  sf::SocketTCP Socket; 
     unsigned int NbSockets; 
     CClient(); 
     int targX; 
     int targY; 
     void Connect(); 
       void RunClient(); 
     void setMyID(int id); 
     int getMyID(); 
     void SendPacket(int packetID, int entityID, int playerID, int command); 
     void SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY); 
     sf::Packet ReSend; 
     std::string ty; 
     sf::IPAddress ServerAddress; 
     std::string inString; 
     sf::Packet ToSend; 
     std::string s; 
     sf::Packet onConnect; 
     static int myID; 
     bool connected; 
     Playern P; 
sf::SocketTCP Client; // Flytter kun på denne
public: 
}; 

//============================================================================= 

#endif

 

 

 

Fungerer ikke, gir ingen error, bare kan ikke sende pakker:

 

 

//============================================================================= 
#ifndef _CCLIENT_H_ 
   #define _CCLIENT_H_ 

#include <SFML/Network.hpp> 
#include <string> 
#include "CEntity.h" 

//============================================================================= 
class CClient{ 
   public: 
     struct Playern 
{ 
  int      PID; 
  int      X; 
   int      Y; 
  int      Dead; 
}; 
     // Packet content 
  int packetID; 
  int entityID; 
  int playerID; 
  int command; 
  // --------------- 
  sf::SelectorTCP selector; 
  sf::SocketTCP Socket; 
     unsigned int NbSockets; 
     CClient(); 
     int targX; 
     int targY; 
     void Connect(); 
       void RunClient(); 
     void setMyID(int id); 
     int getMyID(); 
     void SendPacket(int packetID, int entityID, int playerID, int command); 
     void SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY); 
     sf::Packet ReSend; 
     std::string ty; 
     sf::IPAddress ServerAddress; 
     std::string inString; 
     sf::Packet ToSend; 
     std::string s; 
     sf::Packet onConnect; 
     static int myID; 
     bool connected; 
sf::SocketTCP Client; // Flytter kun på denne
     Playern P; 
public: 
}; 

//============================================================================= 

#endif

 

 

 

Memory access reading violation:

 

 

//============================================================================= 
#ifndef _CCLIENT_H_ 
   #define _CCLIENT_H_ 

#include <SFML/Network.hpp> 
#include <string> 
#include "CEntity.h" 

//============================================================================= 
class CClient{ 
   public: 
     struct Playern 
{ 
  int      PID; 
  int      X; 
   int      Y; 
  int      Dead; 
}; 
     // Packet content 
  int packetID; 
  int entityID; 
  int playerID; 
  int command; 
  // --------------- 
  sf::SelectorTCP selector; 
  sf::SocketTCP Socket; 
     unsigned int NbSockets; 
     CClient(); 
     int targX; 
     int targY; 
sf::SocketTCP Client; // Flytter kun på denne
     void Connect(); 
       void RunClient(); 
     void setMyID(int id); 
     int getMyID(); 
     void SendPacket(int packetID, int entityID, int playerID, int command); 
     void SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY); 
     sf::Packet ReSend; 
     std::string ty; 
     sf::IPAddress ServerAddress; 
     std::string inString; 
     sf::Packet ToSend; 
     std::string s; 
     sf::Packet onConnect; 
     static int myID; 
     bool connected; 
     Playern P; 
public: 
}; 

//============================================================================= 

#endif

 

 

 

Versjon 4, oppryddet med kommentarer, gir memory access reading violation:

 

 

//============================================================================= 
#ifndef _CCLIENT_H_ 
   #define _CCLIENT_H_ 

#include <SFML/Network.hpp> 
#include <string> 
#include "CEntity.h" 

//============================================================================= 
class CClient{ 
public: 

  // Packet content 
  int packetID;   // What type of packet. 
  int entityID;   // EntityID, currently unused. 
  int playerID;   // PlayerID, which player the command is for. 
  int command;   // What command was issued. Move left, cast spell, etc. 

  sf::SelectorTCP selector;      // Selector, used to add a timeout on the recieve to not cause blocking. 
  unsigned int NbSockets;         // Used by the Selector. 

  CClient();                  // Constructor. 

  // Projectile packets only. 
  int targX;      // Target X coordinate for projectiles. 
  int targY;      // Target Y coordinate for projectiles. 
  // --------------- 


  sf::SocketTCP Client;         // The socket used to communicate. 

   void RunClient();            // Runs in the gameLoop, gets incoming packets. 

  // Send packet function for normal commands.    
  void SendPacket(int packetID, int entityID, int playerID, int command); 

  // Send projectile packet function. 
  void SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY); 

  sf::Packet ReSend;         // Packet used when receiving packets. 

  sf::IPAddress ServerAddress;   // IP Address to connect to. 
  sf::Packet ToSend;            // Packet used when sending packets. 
  void Connect();               // Connect function. Sets up connection. 
  sf::Packet onConnect;         // Packet used when receiving info on connect. 
  static int myID;            // ID of your character. 
  bool connected;               // Connected to the server if true. 

private: 

}; 

//============================================================================= 

#endif

 

 

Endret av Cemi
Lenke til kommentar
Videoannonse
Annonse

Dersom jeg endrer rekkefølgen på deklerasjonene, så slutter alt å fungere. Hvorfor?

 

Du må være mye mer spesifikk enn som så.

 

Eksakt hva betyr "slutter alt å fungere" og hvor spesifikt inntreffer feil(ene)? Siden du sliter med minnefeil, hva sier valgrind (eller tilsvarende verktøy)?

 

Det eneste jeg gjør er å flytte på linja:

sf::SocketTCP Client;

 

En ikke urimelig forklaring er at du har en minnefeil i programmet uansett, men den fremprovoseres kun når du flytter på denne deklarasjonen som f.eks. endrer klassestørrelsen (av ren nysgjerrighet, hva sier sizeof på klassene dine i alle de 4 utgavene?). Eller at du aksesserer akkurat utenfor f.eks. targetX, som gjør at starten av sf:SocketTCP-objektet (du vet, gjerne den delen med peker til klasseprototype/virtual table, om den finnes) overskrives med noe søppel.

 

Det å endre på deklarasjonsrekkefølgen i klassen vil ha konsekvenser kun for hvordan objektene av den klassen skal initialiseres (spesielt dersom det er innbyrdes avhengigheter). Utover kan ikke flytting av deklarasjoner være årsaken til minnefeil; det er kun et symptom på at noe annet er galt.

 

valgrind er mitt neste forslag.

Lenke til kommentar

Du må være mye mer spesifikk enn som så.

 

Eksakt hva betyr "slutter alt å fungere" og hvor spesifikt inntreffer feil(ene)? Siden du sliter med minnefeil, hva sier valgrind (eller tilsvarende verktøy)?

 

 

Ved den første endringen, flytter den en linje opp, så får den ikke til å kjøre client.connect(argumenter), men den gir ingen error, connecten går bare ikke gjennom til serveren i det hele tatt. Serveren mottar aldri connect request en gang.

 

Ved den andre så sier den som sagt memory access reading violation

 

Aldri prøvd Valgrind, men skal ta å sjekke det ut :)

 

Takk for svar.

Lenke til kommentar

Ved den første endringen, flytter den en linje opp, så får den ikke til å kjøre client.connect(argumenter), men den gir ingen error, connecten går bare ikke gjennom til serveren i det hele tatt. Serveren mottar aldri connect request en gang.

 

Så connect() timer ut? Skjer det noe spennende på nettverksforbindelsen? (bruk wireshark elns).

 

Aldri prøvd Valgrind, men skal ta å sjekke det ut :)

 

Det er fryktelig vanskelig å råde noe spesielt ift minneaksessfeil. valgrind er et bra førstested. Hvis den rapporterer 0 feil, prøv å reprodusere feilen med det minste mulige eksempelet.

Lenke til kommentar

Om du ikke spesifiserer noe annet blir de forskjellige objektene initialisert i rekkefølgen. Vet ikke om det har noen betydning dog.

 

Kunne hjulpet om du postet litt mer av koden.

 

Har ikke fått prøvd noen av de tidligere rådene enda da helgen har blitt brukt på litt andre ting, så det er mulig at noen av dem vil hjelpe.

 

Her er det som kjøres i selve CClient.cpp dersom det kunne være til nytte.

 

// ------------------------
// Connect to server.
// ------------------------
bool CClient::Connect()
{

   do
   {
	ServerAddress = "127.0.0.1"; // Temporarily static
   }
   while (!ServerAddress.IsValid());

   // Connect to the specified server
   if (Client.Connect(Port, ServerAddress) != sf::Socket::Done)
       return false;

// If connection was successfull the first package will be a package containing an ID used by you and all other connected clients.
if(Client.Receive(onConnect) == sf::Socket::Done)
{	
	onConnect >> myID;
	CClient::myID = myID;
}
else
	return false;

// Set the connected value to true.
connected = true;

// Add the connection to the selector.
selector.Add(Client);

return true;
}

// ------------------------
// Run Client function.
// ------------------------

void CClient::RunClient()
{
if(connected)
{
	// If there are packets incomming receive them, if not time out after 0,01 seconds.
	if(selector.Wait(0.01f) > 0)
	{
	NbSockets = selector.Wait();

	for (unsigned int i = 0; i < NbSockets; ++i)
	{
		ReSend.Clear();

		// If disconnected, set connected to false.
		if(Client.Receive(ReSend) == sf::Socket::Disconnected)
		{
			connected = false;
		}

		// If the packet is readable.
		if(ReSend >> packetID >> entityID >> playerID >> command >> targX >> targY)
		{
// Do something
		}
	}
	}
}

}

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...