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

idontknow

unregistriert

1

25.09.2010, 00:30

[C#] Netzwerkprogrammierung

moin!!

Ich bin langsam leider total durcheinander gekommen mit dem ganzen netzwerk und Protkollkram und bräuchte hier mal etwas aufklärung :).

Prinzipiell geht es um folgendes: Ich geb bei meinem Socket immer TcP als protokolltyp an. Ich bin mir jetzt aber nicht sciher wie ich das ganze auslese/recive! Denn afaik ist es ja so, dass ein Client->Send(N-Bytes) Aufruf nicht zwangsläufig einen Server->Recive()->N "Aufruf" zufolge hat.

Wie behandle ich jetzt also diese Daten? Im Prinzip muss ich doch die Daten immer in einem Buffer zwischenspeichern. Gleichzeitig muss ich durch irgend eine identfikationsnummer oder sonst einer ID erkennen, was für ein Paket/welche größe mein aktuelles Paket ist/hat. Solange ich also nicht genug Daten für mein Paket empfangen habe versuche ich es weiter und sollte ich je mehr Daten haben als mein Paket groß ist entferne ich mein paket aus dem Buffer und schick es in die "Bearbeitung" durch den Server?

Mein grundlegendes Problem ist (ganz kurz mit "Pseudo"-Code zusammengefasst):

Packet = {Header, Daten, Größe, Typ,...} -> Serialize->ByteArray -> Client.Send -- INTERNET/TCP --> Server.Recive -> ByteArray -> "Re"serialize -> Packet = {Header, Daten, Größe, Typ,...}

Das ganze verwirrt mich mittlerweile doch sehr (vmtl muss ich einfach mal ausschlafen^^) und wäre nett wenn michd a mal wer aufklären könnte wie ich das anstelle, dass meine geschickten nachrichten auch komplett beim Server/Client ankommen (geht ja in beide Richtungen!)

Pseudo Code wäre btw auch sehr nice, weil ich wie gesagt mittlerweile gar nicht mehr durchblicke :(

mfg

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

25.09.2010, 03:34

Naja eig hast du die antwort schon selbst gegeben. Definiere dir einen Paketheader, lese diesen aus und entscheide dann anhand dieser info wieviele bytes zusätzlich zum Paketheader zu auslesen musst.

Also ich würde es mal mit ausschlafen versuchen ;)
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.

idontknow

unregistriert

3

25.09.2010, 10:28

Das ganze sdchaut jetzt so aus, wobei mein Header immer 12 Bytes groß ist und mit 4 Chars beginnt (random Zeichenkette zum bestimmen, ob es ein Header ist) und 2 Ints mit FileLänge und nem Type.

Gets in die richtige Richtung? Zum testen bin ich leider noch nicht gekommen..

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
private void send(byte[] msg, int type)
        {
            byte[] headerID = new byte[4];
            headerID[0] = Convert.ToByte('M');
            headerID[1] = Convert.ToByte('H');
            headerID[2] = Convert.ToByte('H');
            headerID[3] = Convert.ToByte('0');
            byte[] l = new byte[4];
            l = BitConverter.GetBytes(msg.Length);
            byte[] t = new byte[4];
            t = BitConverter.GetBytes(type);


            client.Send(headerID);
            client.Send(l);
            client.Send(t);
            client.Send(msg);
        }

        private void recive()
        {
            byte[] buffer = new byte[256];
            byte[] header = new byte[12];
            byte[] file = null;

            bool headerSent = false;
            int bytesRecived = 0;

            char[] headerID = null;
            int length = 0;
            int type = 0;

            while (true)
            {
                if (!headerSent)
                {
                    if (bytesRecived < HEADERSIZE)
                    {
                        bytesRecived += client.Receive(buffer, bytesRecived, HEADERSIZE - bytesRecived, 0);
                    }
                    if (bytesRecived >= HEADERSIZE)
                    {
                        headerID = new char[4];
                        Array.Copy(buffer, 0, header, 0, HEADERSIZE);
                        bytesRecived = 0;
                        headerID[0] = BitConverter.ToChar(header, 0x00);
                        headerID[1] = BitConverter.ToChar(header, 0x01);
                        headerID[2] = BitConverter.ToChar(header, 0x02);
                        headerID[3] = BitConverter.ToChar(header, 0x03);
                        length = BitConverter.ToInt32(header, 0x04);
                        type = BitConverter.ToInt32(header, 0x08);

                        if (headerID[0] == 'M' &&
                            headerID[1] == 'H' &&
                            headerID[2] == 'H' &&
                            headerID[3] == '0')
                        {
                            headerSent = true;
                            file = new byte[length];
                        }
                        else
                        {
                            // kein Header angekommen :o
                        }
                    }
                }
                else
                {
                    // header ist gesetzt!!
                    if (bytesRecived < length)
                    {
                        bytesRecived += client.Receive(buffer, bytesRecived, length - bytesRecived, 0);
                    }
                    if (bytesRecived >= length)
                    {
                        // datei ist angekommen!
                        parseMessage(file, type);
                        headerSent = false;
                        header = new byte[12];
                        buffer = new byte[256];
                        bytesRecived = 0;
                        length = 0;
                        type = 0;

                    }

                }

            }

        }

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

25.09.2010, 10:58

Die 4 Bytes zum Testen, ob es ein Header ist, die sind überflüssig solange dein Algorithmus keinen Bug hat. Denn TCP verliert keine Daten und würfelt sie auch nicht durcheinander. Und auch für Sicherheitszwecke macht es keinen Sinn. Ich würde es also weglassen.
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