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

1

27.08.2012, 16:29

SFML SocketTCP empfängt nichts

Einleitung:
Beim Versuch ein 2D Sidescrolling Game zu programmieren, wollte ich probieren einen zweiten Spieler auf die Map hinzu zu fügen (per Netzwerk). Ich fing vorerst an, kleine Testprogramme (basierend auf dem SFML "Tutorial ") zu schreiben, die auch nach ein paar Problemen funktionierten. Schließlich versuchte ich den Code in eine Klasse umzuschreiben und in das Programm einzufügen.

Zustand:
Der Server und der Client wird wie in dem Tutorial gestartet und connected auch sofort. Auch das Einpacken von Variablen in ein Packet funktioniert einwandfrei.

Problem:
Jedoch empfängt der Server das Paket nicht.

CODE:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//Spieler A = Spieler, der das Spiel leitet (Server)
//Spieler B = Zweiter Spieler (Client)
void Network::ClientRun (float B_X_Pos, float B_Y_Pos,  float B_AnimationNR, int B_SkillID, bool B_Jump,
        float &A_X_Pos, float &A_Y_Pos,  float &A_AnimationNR, int &A_SkillID, bool &A_Jump)
{


    if (Client.IsValid () == false) //Prüfen, ob die Verbindung noch steht
        std::cout << "Disconected" << std::endl;


    if (!(ToSend << B_X_Pos << B_Y_Pos << B_AnimationNR << B_SkillID << B_Jump)) //Packet senden
        return;

    if (!(Recieve >>  A_X_Pos >> A_Y_Pos >> A_AnimationNR >> A_SkillID >> B_Jump)) //Packet empfangen
        return;
}


void Network::ServerRun (float A_X_Pos, float A_Y_Pos,  float A_AnimationNR, int A_SkillID, bool A_Jump,
        float &B_X_Pos, float &B_Y_Pos,  float &B_AnimationNR, int &B_SkillID, bool &B_Jump)
{

    if (Server.IsValid () == false) //Prüfen, ob die Verbindung noch steht
        std::cout << "Disconected" << std::endl;

    if (!(Recieve >> NX_Pos >>  NY_Pos >> NAnimation >> NSkillID >> NJump)) //Packetempfangen
        return;

    std::cout << "Server: Empfangen" << std::endl;
    
    if (!(ToSend << A_X_Pos << A_Y_Pos << A_AnimationNR << A_SkillID << B_Jump)) //Packet versenden
        return;


    std::cout << "Server: Gesendet" << std::endl;

}



Zwischeninformation:

-Die Funktionen werden in der Eventschleifen eingesetzt.
-Es kommt kein Disconnect vor.



mfg. RunRanger
Programmiersprache: C++
Fortschritt: Grundkenntnissse

2

27.08.2012, 21:49

Schau dir am besten nochmal die Tutorial Reihe dazu in Ruhe an, du scheinst es nicht wirklich verstanden zu haben...
Und wozu brauchst du Referenzen bei Grund Datentypen?

3

27.08.2012, 22:52

Danke für die Antwort.


Ich benutze Referenzen, um die Werte des Spielers aus der Funktion einfach übertragen kann. Ich hab es mir komischer Weise angewöhnt, auch wenn eigentlich Zeiger bevorzugt werden.

Ich hab mir nochmals das Tutorial durchgelesen und mein Code nochmals angepasst (den vorherigen Code hatte ich während einer Websuche entdeckt), jedoch hat sich nichts geändert. Der Server empfängt kein Packet :huh:
Programmiersprache: C++
Fortschritt: Grundkenntnissse

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

28.08.2012, 09:30

Ich benutze Referenzen, um die Werte des Spielers aus der Funktion einfach übertragen kann. Ich hab es mir komischer Weise angewöhnt, auch wenn eigentlich Zeiger bevorzugt werden.

Ich glaube Du hast die Frage falsch verstanden. Es macht keinen Unterschied von der Performance her, ob man Referenzen oder native Datentypen übergibt, falls diese gleich groß sind, was bei Dir der Fall ist. Es verwirrt genau genommen wohl sogar eher. Auch Pointer würden da keinen Sinn machen, sogar im Gegenteil, sie wären da für das Verständnis sogar hinderlich, weil Referenzen und Pointer normalerweise benutzt werden, damit der Inhalt von Variablen innerhalb anderer Funktionen geändert werden kann, wo Du allerdings nur lesend zugreifen willst.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

28.08.2012, 14:14

Setz mal die funktionen in einer normal schleife und nicht in der Event schleife, wenn es weiterhin nicht klappt dann kann ich dir ein kleines Beispiel geben das du dich da dran orientieren kannst.

6

28.08.2012, 16:03

In deinem Quelltext oben fehlt halt auch eine Menge (so kann man dir auch nicht konkret helfen) man sieht nur das du die Verbindung validierst,
und überprüfst ob es ein Fehler beim hinzufügen der Werte in die jeweiligen Pakete gab. Ich sehe in keiner Zeile das du die
send() oder receive() Funktion aufrufst... Weder noch das du an einem Port horchst oder überhaupt auf einen Client wartest.

Deswegen solltest du dir wirklich mal die von dir oben selber genannte Tutorial Reihe in Ruhe durchlesen.
Wenn es danach immer noch an Verständnis fehlt, kannst du dich ja wieder melden, ich schicke dir dann gerne
eine Zeichnung wo das Prinzip einer simplen Server zu Client Verbindung auf sehr einfache und verständliche Weise gezeigt wird. ^^

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Jack« (28.08.2012, 16:08)


7

28.08.2012, 20:16

Danke für die vielen Antworten.

hmmm...ich hab nochmals dran rumgebaut, jedoch komm ich irgendwie nicht dahinter...




Network.cpp
[spolier]

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Network.hpp>
#include <iostream>
#include "Network.hpp"


////////////////////////////////////////////////////////////
/// Create a client and connect it to a running server
///
////////////////////////////////////////////////////////////
void Network::DoClientTCP(unsigned short Port, sf::IPAddress NServerAddress)
{
    

    ServerAddress = NServerAddress;
  
  

    // Connect to the specified server
    if (Client.Connect(Port, ClientAddress.GetLocalAddress ()) != sf::Socket::Done)
    {
        std::cout << "Failed to connect to the server" << std::endl;
        return;
    }
    Connected = true;
    std::cout << "Connected to server " << ServerAddress << std::endl;


    std::cout << "Client "<< std::endl;





}


////////////////////////////////////////////////////////////
/// Launch a server and wait for incoming connections
///
////////////////////////////////////////////////////////////
void Network::DoServerTCP(unsigned short Port)
{
    
    // Create a TCP socket for communicating with clients
   

    // Listen to a port for incoming connections
    if (!Server.Listen(Port))
        return;
    std::cout << "Server is listening to port " << Port << ", waiting for connections... " << std::endl;

    // Wait for a connection
 
    Server.Accept(Clien2t, &ClientAddress);
    std::cout << "Client connected : " << ClientAddress << std::endl;

    std::cout << "Server "<< std::endl;

}




//////////////////
//Datenaustausch//
//////////////////

//Spieler A = Spieler, der das Spiel leitet (Server)
//Spieler B = Zweiter Spieler (Client)
void Network::ClientRun (float B_X_Pos, float B_Y_Pos,  float B_AnimationNR, int B_SkillID,  bool B_Jump,
        float &A_X_Pos, float &A_Y_Pos,  float &A_AnimationNR, int &A_SkillID, bool &A_Jump)

{

    if (Client.IsValid () == false) //Prüfen, ob die Verbindung noch steht
        std::cout << "Disconected" << std::endl;


    ToSend << B_X_Pos << B_Y_Pos << B_AnimationNR << B_SkillID << B_Jump;


    if (Client.Send (ToSend)!= sf::Socket::Done) //Packet senden
        return;

    Client.Send (ToSend);


    std::cout << "Client: gesendet" << std::endl;

    if (!(Recieve >>  A_X_Pos >> A_Y_Pos >> A_AnimationNR >> A_SkillID >> B_Jump)) //Packet empfangen
        return;

    std::cout << "Client: empfangen" << std::endl;
}


void Network::ServerRun (float A_X_Pos, float A_Y_Pos,  float A_AnimationNR, int A_SkillID, bool A_Jump,
         float &B_X_Pos, float &B_Y_Pos,  float &B_AnimationNR, int &B_SkillID, bool &B_Jump)
{

    if (Server.IsValid () == false) //Prüfen, ob die Verbindung noch steht
        std::cout << "Disconected" << std::endl;

    if (Server.Receive (Recieve) != sf::Socket::Done) //Packetempfangen
        return;

    Server.Receive (Recieve);

    Recieve >> NX_Pos >>  NY_Pos >> NAnimation >> NSkillID >> NJump;

    std::cout << "Server: Empfangen" << std::endl;
    
    if (!(ToSend << A_X_Pos << A_Y_Pos << A_AnimationNR << A_SkillID << B_Jump)) //Packet versenden
        return;


    std::cout << "Server: Gesendet" << std::endl;
    Sended = true;
}

[/spoiler]




Game.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
 void Game::ServerClientRun ()
 {
    if (Network.Connected == true)
    {

        if (ClientOn == true)
        {
            Network.ClientRun (PlayerA.m_fXPos, PlayerA.m_fYPos, PlayerA.m_Animation, PlayerA.SkillID, PlayerA.b_Jump,
                PlayerB.m_fXPos, PlayerB.m_fYPos, PlayerB.m_Animation, PlayerB.SkillID, PlayerB.Jump);
        }
        if (ClientOn == false)
        {
            Network.ServerRun (PlayerA.m_fXPos, PlayerA.m_fYPos, PlayerA.m_Animation, PlayerA.SkillID, PlayerA.b_Jump,
                PlayerB.m_fXPos, PlayerB.m_fYPos, PlayerB.m_Animation, PlayerB.SkillID, PlayerB.Jump);
        }
    }
 
 }



void Game::Run ()
{   
    const sf::Input& Input = Fenster.GetInput ();
    
    while (running == true)
    {

        Fenster.Clear ();
    
        Fenster.Draw(Map.MBackround);
        Fenster.Draw (PlayerB.MSecondPlayer);
        Fenster.Draw(PlayerA.MPlayer);



        PlayerA.All (Input, Fenster);
        Map.GroundTreffen (PlayerA.m_fXPos, PlayerA.m_fYPos, PlayerA.b_Ground, PlayerA.b_DownStair);

        Fenster.Display ();
        Event ();

        
        ServerClientRun ();

    }
}

 



Der Server wird mit "Network.DoServerTCP (2357);" gestartet
und der Client mit "Network.DoClientTCP (2357, C_IP);".


@BlueCobold: Ich will mit den Referenzen dem jeweiligen Spieler die Koordinaten des anderen geben und abspeichern, damit ich diese später für das Rendern des 2. Spielers nutzen kann.

mfg. RunRanger
Programmiersprache: C++
Fortschritt: Grundkenntnissse

8

28.08.2012, 22:22

Falsch:

C-/C++-Quelltext

1
2
    if (!(Recieve >>  A_X_Pos >> A_Y_Pos >> A_AnimationNR >> A_SkillID >> B_Jump)) //Packet empfangen
        return;


Falsch:

C-/C++-Quelltext

1
2
    if (!(ToSend << A_X_Pos << A_Y_Pos << A_AnimationNR << A_SkillID << B_Jump)) //Packet versenden
        return;


Schau dir diese Zeilen genauer an, denk darüber nach und schreib es dann richtig um. Die Fehler müsstest du
eigentlich problemlos finden, weil du es ja jeweils einige Zeilen davor richtig angewandt hast.

Übrigens, wenn du Quelltext zeigst wäre es Vorteilhaft diesen aufs wesentliche zu kürzen, am besten du machst daraus
ein simples Programm welches nur aus einer Haupt Datei besteht. Manchmal ist es dann sogar so, dass man während
des umschreibens die Fehler findet. Das aber nur am Rande. ^^

@ Referenzen
Du scheinst allem Anschein nach den Sinn hinter den Referenzen noch nicht ganz verstanden zu haben,
lese dir am besten in deinem Buch der Wahl das Thema nochmal genauer durch. ;)

9

29.08.2012, 22:44

Nochmals abgespeckt und präzise geändert:
-die Variablen in eine Struktur eingepackt
-per return die erhaltene Struktur ausgeben
-> keine Referenzen
-Fehler korrigiert.


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Ablage Network::ClientRun (Ablage B_Ablage)
{
    if (Client.IsValid () == false) //Prüfen, ob die Verbindung noch steht
        std::cout << "Disconected" << std::endl;

    ToSend << B_Ablage;


    if (Client.Send (ToSend)!= sf::Socket::Done) //Packet senden
        std::cout << "Client: Senden Fehlgeschlagen" << std::endl;



    if (Client.Receive (Receive) != sf::Socket::Done) //Packet empfangen
        std::cout << "Client: Empfangen fehlgeschlagen" << std::endl;
    else
    {
        Receive >> C;
        std::cout << "Client: empfangen" << std::endl;
        return C;
    }
}



Ablage Network::ServerRun (Ablage A_Ablage)
{

    if (Client.Receive (Receive) != sf::Socket::Done) //Packetempfangen
        std::cout << "Server: Empfangen Fehlgeschlagen" << std::endl;
    else
    {
        Server.Receive (Receive);
        Receive >> C;
        return C;
    }

    ToSend << A_Ablage;
    if (Client.Send (ToSend)!= sf::Socket::Done) //Packet versenden
        std::cout << "Server: Gesendet Fehlgeschlagen" << std::endl;

    else
         std::cout << "Server: Gesendet" << std::endl;

}



Resultat:
-der Client sendet die Datei (1x)
-der Server antwortet beim Empfangen nicht (Programm stürzt aber NICHT ab)


PS: Den Quelltext werd ich morgen versuchen in eine main zu packen.
Programmiersprache: C++
Fortschritt: Grundkenntnissse

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »RunRanger« (30.08.2012, 14:22)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

10

30.08.2012, 03:58

Bitte lern erstmal die Grundlagen bevor du dich an die Netzwerkprogrammierung wagst. Es gibt nicht viele Gebiete, die mehr Erfahrung erfordern...
"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?

Werbeanzeige