Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Geheim

Treue Seele

  • »Geheim« ist der Autor dieses Themas

Beiträge: 202

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

1

29.03.2012, 21:23

SFML 2.0 TcpSocket Zeigerproblem

Hallo Leute,
Ich habe einen nervigen Fehler und weiß leider nicht mehr weiter, hat wahrscheinlich garnichts mit Sockets zu tun, aber das weiß ich ja noch nicht^^

Ich hab mir einen kleinen Chat geschrieben, funktioniert auch alles wunderbar, aber zurzeit können die Clients nur mit dem Server schreiben und nicht untereinander, drum wollt ich das ändern, aber da kommt mein "komischer" Fehler ins Spiel!

Zuerst habe ich die Clients in einem Vector gehabt:

C-/C++-Quelltext

1
2
std::vector<sf::TcpSocket*> vDaten;
std::vector<sf::TcpSocket*>::iterator i;


so funktioniert alles wunderbar ;)
Jetz wollt ich das ganze auf eine Klasse verlegen die folgendermaßen aussieht:

Client.h:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <SFML/Network.hpp>
#ifndef CLIENT_H
#define CLIENT_H

class Client
{
    private:
        sf::TcpSocket* Socket;
    public:
        Client(sf::TcpSocket* TcpSocket);
        ~Client();
        sf::TcpSocket* GetClient();
};
#endif


und Client.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <SFML/Network.hpp>
#include "client.h"

Client::Client(sf::TcpSocket* TcpSocket)
{
    Socket = TcpSocket;
}

Client::~Client()
{
    delete(Socket);
}

sf::TcpSocket* Client::GetClient()
{
    return Socket;
}


Ich habe in der main bei dem Vector das <sf::TcpSocket*> mit <Client> ersetzt und an der Stelle wo ich das Socket brauche einfach die Funktion GetClient() benutzt. Mit dem Debugger hab ich schon herausgefunden, dass das Problem schon an der Stelle passiert wo ich einen neuverbundenen Client dem Vector hinzufüge:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(Selector.IsReady(Listener))
    {
        //Bereit und eine Verbindung ist da
        sf::TcpSocket* Socket = new sf::TcpSocket;
        if(Listener.Accept(*Socket) == sf::Socket::Done)
        {
            //Client zur Liste hinzufügen
            vDaten.push_back(Client(Socket));  .....>   "Hier sagt dann der Client schon, dass der Server disconnected hat, was nicht stimmt!"

            //Client dem Selector hinzufügen
            Selector.Add(*Socket);      //Derefferenzieren, damit es eine Referenz wird!

            Socket->Receive(Buffer, sizeof(Buffer), Received);
            std::cout<<"Neuer Client verbunden: "<<Buffer<<" ("<<Socket->GetRemoteAddress()<<")\a"<<std::endl<<std::endl;

            //Antwort senden
            Message = Buffer;
            Socket->Send(Message.c_str(), Message.size() + 1);
        }
    }


Ich hoff ihr könnt mir weiterhelfen,
MfG Geheim!

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

30.03.2012, 14:24

In Zeile 8 wird der Destruktor aufgerufen...
Ausserdem kriegst du unter umständen ein Memoryleak.

Wenn du immernoch aus C++ für Spieleprogrammierer abtippst solltest du dir überlegen ob du dir nicht was einfacheres suchst um die Grundlagen zu festigen...
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Geheim

Treue Seele

  • »Geheim« ist der Autor dieses Themas

Beiträge: 202

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

3

30.03.2012, 22:22

Danke für die Antwort!
Ich tippe schon ewig von keinem Buch mehr ab ;)
Aber ich glaube ich weiß was man tun muss, selbst einen Kopierkonstruktor schreiben?

Edit: Wenns so gehen würde, schaff ich es leider nicht weil sich alles wegen const wiederspricht^^

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Geheim« (30.03.2012, 22:52)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

4

31.03.2012, 10:10

Ich tippe schon ewig von keinem Buch mehr ab ;)

Das glaub ich dir nicht.

Zitat von »Geheim«

C-/C++-Quelltext

1
2
std::vector<sf::TcpSocket*> vDaten;
std::vector<sf::TcpSocket*>::iterator i;

Das ist garantiert aus C++ für Spieleprogrammierer abgeschrieben...

Ein eigener Kopierkonstruktor bringt dir hier nichts, weil es überhaupt nicht sinnvoll wäre Client zu kopieren(du könntest von sf::noncopyable erben um das zu garantieren).
Sorge einfach dafür, dass das Object im Vector nicht direkt kopiert werden muss.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Geheim

Treue Seele

  • »Geheim« ist der Autor dieses Themas

Beiträge: 202

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

5

31.03.2012, 13:23

Das glaub ich dir nicht.

Das ist garantiert aus C++ für Spieleprogrammierer abgeschrieben...
Musst du nicht^^ Aber ich habs von der Doku: http://www.sfml-dev.org/documentation/2.…ketSelector.php
Bei dem ersten Beispiel :

C-/C++-Quelltext

1
2
// Create a list to store the future clients
 std::list<sf::TcpSocket*> clients;


Habs halt mit einem vector statt der list gemacht und den iterator schon vorher deklariert, aber sonst ist es von dort ;)
Klar ich benutz noch das vDaten von dem Buch, aber das hab ich mir so gemerkt und ich benutz es auch gern, obwohl ich weiß, dass ichs nicht sollte^^

Ich weiß nicht wie ich das machen soll mit dem nicht direkt kopieren, hab zurzeit eine Notlösung gefunden und mir einen Bool erstellt, der erst beim 2. Aufruf vom Destruktor den Zeiger löscht...

6

31.03.2012, 21:30

vDaten.push_back(Client(Socket));
Diese Zeile muss einfach nach:
vDaten.push_back(new Client(Socket));
umgeschrieben werden, damit die Clientinstanz nicht sofort wieder gelöscht wird. Durch das Löschen der Client-Instanz wird dann ebenfalls das Socket gelöscht, wodurch sich wohl die Verbindung trennt.

vDaten muss dann natürlich auch entsprechend zu <Client *> umgeschrieben werden.

Geheim

Treue Seele

  • »Geheim« ist der Autor dieses Themas

Beiträge: 202

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

7

01.04.2012, 14:08

Achso ist das, mal wieder was dazugelernt ;)
Stimmt funktioniert so, danke dir!

Werbeanzeige