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

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

11

04.08.2015, 22:33

Zu der Ausführung. Ich könnte jetzt versuchen mich an all die Probleme (fragmentierte Pakete etc.pp.) und Kniffe zu erinnern, die mich mehrere Tage Debugging gekostet haben, auf die Gefahr hin, dass ich 50% vergesse. Alternativ könnte ich folgende Auszüge einer funktionierenden Lib anbieten (aus http://svn.code.sf.net/p/syncsys/code/src/network.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
void BasicClient::ThreadUpdate(unsigned acttime)
{
    if(state == CONNECTING && !tryconnect())
        return;

    TIMEVAL     time;
    fd_set      readset;

    time.tv_sec = 0;
    time.tv_usec = 1000;
    
    FD_ZERO(&readset);
    FD_SET(Socket, &readset);

    if(-1 == select(static_cast<int>(Socket + 1), &readset, NULL, NULL, &time))
    {
        geterror();//EDIT: has to be logged
        state = FAILED;
    }

    if(FD_ISSET(Socket, &readset))
        ClientCallback();
}

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
void Clientclass::ClientCallback(void)
{
    int rl = recv(Socket, const_cast<char*>(RecvBuffer.GetDataFromWOffset()), (int)RecvBuffer.GetUnusedSize(), 0);
    if(rl == -1 || rl == 0)// occur an error?
    {
        state = FAILED;
        geterror();
        return;
    }

    RecvBuffer.SetWriteOffset(rl + RecvBuffer.GetWriteOffset());

    while(RecvBuffer.GetWriteOffset() >= PAKETSIZE)
    {
        if(!ParsedHeader)
        {
            ParsedHeader = true;

            //parse data into header
            RecvPacket.ReadHeader(RecvBuffer);

            //is the packet correct?
            if(!IsHeaderOkay(RecvPacket))
            {
                HandleErrorMessage("Message from syncsys: Header is corrupted");
                state = FAILED;
                return;
            }

            unsigned CompleteSize = RecvPacket.ZippedSize + PAKETSIZE;
            if(CompleteSize < RecvBuffer.GetWriteOffset())  CompleteSize = RecvBuffer.GetWriteOffset();
            CheckAndDoResize(RecvBuffer, CompleteSize, true);
            
            if(RecvPacket.MSG == CloseMsg)
            {
                Send(RecvPacket);
                if(0 != closesocket(Socket))
                    geterror();
                Socket = (SOCKET)-1;
                state = CLOSED;
                break;
            }
        }
        unsigned int CompleteSize = RecvPacket.ZippedSize + PAKETSIZE;
        //are there enough buffered data?
        if(RecvBuffer.GetWriteOffset() >= CompleteSize)
        {
                    [... ein wenig dekompressionskrams später...]
            
            if(!AsyncCallbackFunc(RecvPacket))
                SyncList.push_back(RecvPacket, true);

            //reset RecvLen + Buffer, cleaning up etc.
            NumRecvPackets++;
            SizeRecvPackets += CompleteSize;

            RecvBuffer.ShiftBuffer(true, CompleteSize);
            ParsedHeader    = false;
        }
        else
            break;//lets go away
    }
}

Vielleicht liefert das schonmal einen brauchbaren Ansatz. Bei Detailfragen einfach losschießen.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

12

05.08.2015, 05:07

Wenn ich meinen Senf dazu geben darf:
1. bitte Bitte BITTE kein peer2peer (sag es nur, weil es hier in den Raum geworfen wurde. Der zuerst genannte Server-Client vermeidet viele konzeptionelle Probleme).


was hat man den für konzeptionelle Probleme?

Du machst über einen Server jeden mit jedem bekannt. Danach steht das peer2peer und der Vermittlungs-Server wird nicht mehr weiter gebraucht.

Nun wird ein "Host" nach bestimmten Kriterien unter allen Beteiligten ausgewählt. Anschliessend wird auf dem Auserwählten (Host) der Server gestartet und alle Clienten kommunizieren mit dem Server und der Server sendet die spielrelevanten Daten an die Clienten.

Im Grunde hat man dann auch eine Client-Server Architektur. Und damit gibt es die "konzeptionellen Probleme" nicht mehr.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

13

05.08.2015, 06:34

Das wäre dann aber kein p2p, sondern ein Server-Client.
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]

Werbeanzeige