Seite 2 von 3

Verfasst: 21.06.2006 14:17
von AND51
@ 0: Das stimt, ich meinte Poke, habe im Eifer des Gefechts aber den Fehler nich bemerkt.

Jednefalls war meine Frage, wie SendNetworkData genau arbeitet, ob es Daten inkl. ihres Typs überträgt, soll heißen:

SendNetworkString sendet immer nur Strings, Zahlen mmuss man konvertieren. Als ich mich mal mit dem ICQ-Protokoll beschäftigt habe, kam ich an einer Stelle nicht weiter, weil ich eine Zahl senden musste und jemand sagte mir: Dazu musst du SendNetworkData() nehmen. Ich kann mir die Befehle besser merken, wenn ich weiß, wie er arebeitet, deshalb frage ich.

Verfasst: 21.06.2006 15:04
von #NULL
wenn du nur einen einzelnen wert senden willst, müsste es ja auch so gehn:

Code: Alles auswählen

var.l=666
SendNetworkData(Verbindung, @var, SizeOf(var) )
der typ ist für SendNetworkData() uninterressant, es wird einfach byteweise übertragen. wie die bitfelder auf der anderen seite wieder interpretiert werden ist deine sache. also ob z.b. ein übertragener buffer mit der länge 8 byte nun ein quad, oder zwei longs, oder vier word ect. darstellen sollen. da musst du zusätzliche infos schicken, oder gleich ein protokol baun (oder du weisst halt einfach aus einem anderen grund, was du verschickt hast, z.b. weil du generell nur zahlen vom gleichen typ verschickst).

Verfasst: 21.06.2006 17:03
von AND51
OK, und wenn ich nun mit deinem Codeschnipsel Daten sendete, dann werden sie ja auch in einen AllocateMemory() geschrieben, nicht? Kann ich dann auch mit pointern so wie du da arbeiten? Wenn ja, wie müsste das aussehen?

Verfasst: 21.06.2006 17:45
von #NULL
ich habe ja eigentlich keinen pointer verwendet, sondern die adresse der variablen direkt an die prozedur übergeben. mit
ReceiveNetworkData(Verbindung, @var, SizeOf(var) )
müsstes du dann auf der anderen seite den wert problemlos speichern können, ohne dass auf irgendeiner seite der verbindung dynamisch speicher alloziiert wurde (var ist hier natürlich eine variable DIESES programms, hat also nichts mit der variablen var auf der senderseite zu tun).

Verfasst: 21.06.2006 18:41
von PMV
Der unterschied zwischen SendNetworkString() und SendNetworkData()
ist sehr gering. Im prinzip hätte man sich auch SendNetworkString()
sparen können, aber das würde sicher einige Anfänger zur weisglut
bringen :lol:

Wenn du einen Text in einer Variablen gespeichert hast und willst ihn
senden, kannst du die einfachere Möglichkeit
SendNetworkString(CliendID, Text$)
nehmen, oder du verwendest die andere
SendNetworkData(ClientID, @Text$, Len(Text$))
Hoffe das Beispiel ist verständlich.

SendNetworkData() versendet den angegebenen Speicherbereich und
SendNetworkString() sendet halt den übergebenen String. Im prinzip ja
auch nur ein Speicherbereich :D .

@Stromberg
Zu den Buffers. Da du hier nur schreibst und keinen Code gepostet hat,
kann man nicht genau sagen, ob es so sinnvoll ist, wie du es verwendest
;-)
Aber generell braucht ma erst mal nur einen Buffer. Dieser ist dazu da,
um die emfpangenden Daten zu speichern. ReceiveNetworkData() gibt
zudem die Länge der Empfangenden Daten zurück (in Byte). Ist diese so
groß wie der letzte Parameter, so sind noch weitere Daten zu empfangen
und ReceiveNetworkData() sollte wiederholt ausgeführt werden, um diese
auch noch zu bekommen.

Dazu noch folgendes. Daten die nacheinander gesendet werden, können
gleichzeitig beim Empfänger ankommen. ReceiveNetworkData()
unterscheidet dann nicht und schreibt sämtliche Daten in den Speicher.
Wenn ihr also immer nur schaut, welchen wert das erste Byte hat und
dementsprechend mit dem rest verfährt, ist es sehr wahrscheinlich, das
öfters mal 1 Nachricht nicht nur übersprungen wird, sondern fälchlicher
weise mit der Nachricht davor verbunden wird. Das ist auch nicht auf
unmitelbar Folgende Nachrichten beschränkt, wenn das Programm gerade
stockt können durch aus ein duzend nachrichten oder mehr plötzlich zum
verarbeiten anliegen.

Wenn dann dabei 5000 Byte (die größe deines Buffers so weit ich weis)
übertrumpft werden, also z.b. 1. Nachricht hat 1000 Byte + 2. Nachricht
mit 3500 Byte + die 3. Nachricht mit 2500 Byte = 7000 Byte, wird die 2.
Nachricht zur 1. Nachricht hinzugefügt und als 1. Nachricht verarbeitet, die
3. Nachricht wird teilweise zur 1. Nachricht hinzugefügt und der rest als
eigenständige Nachricht verarbeitet, was natürlich zu fehlinterpretationen
führt.

Und ganz am Rande, AOL wird sich für dieses Projekt sicher nicht
interezieren :D ... da müsster keine Angst haben. So lang ihr noch
Anfänger-Projekte habt und die Grunddinge lernt, wird euch keiner an
eure Programme gehen *gg*

MFG PMV

Verfasst: 21.06.2006 19:45
von Stromberg
Hallo PMV,

danke erstmal für die Antwort.

Zunächst: Dass AOL und Co. kein Interesse an unseren "Programmen" haben, ist mir auch klar. War auch eigentlich eher als Witz gemeint. :)


Wie kann es nun umgehen, dass zwei Nachrichten gleichzeitig ankommen und so deren Inhalt fehlinterpretiert wird? Theoretisch müsste es doch reichen, neben dem Zeichen am Anfang des Strings noch eines am Ende zu machen, damit eine Nachricht eindeutig zuzuordnen ist, oder übersehe ich da etwas?

Verfasst: 21.06.2006 20:18
von PMV
Das Zeichen (Zeichenfolge) am Ende ist eine Möglichkeit, aber wähle gut,
es darf nämlich ansonnsten nie mals in den Daten auftauchen. Zudem
muss es möglich sein auch Nachrichten zu bearbeiten, die über die
vorgegebene Speicherlänge hinaus gehen, damit nicht das passiert, was
ich oben beschrieben hab.

Eine andere Möglichkeit wäre das Senden der Länge der Daten.
Du könntest z.B. am anfang ein Word senden, also eine 2 Byte große Zahl
und anhand dieser dann deinen Speicherbereich resservieren. Nun
empfängst du die Daten, lässt diese in den Speicherbereich schreiben mit
der Länge, die du bekommen hast. Anschließend kannst du die Daten
dann auswerten. Und nicht vergessen den Speicher wieder frei zu geben
(es sei denn, du erweiterst nur immer den selben).

Aber du solltest vorher noch Sicherheiten einbauen (Checksumme z.B.).
Ein Chatserver darf nie mals alle Daten die er empfängt auch bearbeiten.
Er muss überprüfen, ob diese auch von einer vertrauenswürdigen Quelle
(Client) stammen. Ansonnsten kann sich jeder "Möchtegern-Hacker" an
deinem Server Späßchen erlauben :wink: ... das ist aber ein anderes
Thema wozu so wie so besser das Internet (Google) verwendet werden
sollte. Alternativ auch die Suche im Forum hier ... da gibs sicher auch die
ein oder andere Info.

Ansonnsten ist die Sicherheit auch nur dafür nötig, wenn das ganze nicht
nur Privat genutzt werden soll oder deine Nutzter einen Hang zum
"Hacken" haben, also Leute ärgern ^_^ ... das musst du aber
entscheiden.

MFG PMV

Verfasst: 21.06.2006 21:40
von AND51
@ PMV: Ist dann auch das hier möglich?
Achtung! ich sende keine String, sondern irgendeine zahl, ob float oder long!
Senden:

Code: Alles auswählen

zahl.l=7
SendNetworkData(ClientID, @zahl, 1)
Und kann ich das dann so empfangen?

Code: Alles auswählen

empf_zahl.l=0
ReceiveNetworkData(ID, @empf_zahl, 1000)
??

Verfasst: 21.06.2006 22:04
von #NULL
im ersten code sendest du aber nur 1 byte der 4 long bytes ! da kann natürlich quatsch ankommen.
und im zweiten code schreibt er mehr als 4 bytes des long an die adresse der variblen, wenn die gesendeten daten grösser als 4 bytes sind !

Verfasst: 21.06.2006 22:28
von #NULL
wenn du so was versendest:

Code: Alles auswählen

n.w=257
SendNetworkData(ConnectionID, @n, 4)
und so empfängst:

Code: Alles auswählen

ReceiveNetworkData(ClientID, Buffer, 1000)
MessageRequester( "sent", Str(PeekB(Buffer)), 0)
dann erhältst du "1" als ausgabe, also das zweite byte (der zahl 257). würd gern mal wissen ob die bytes schon im speicher im big-endian liegen, oder erst im big-endian versendet werden.(?)

//...liegt scheinbar am versenden