Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
26.03.2007, 13:40
Felheart



Hi,

Ich hab ne TCP verbindung über welche ich gerne daten versenden würde.

Ich habe mir also eine architektur ausgedacht mit deren hilfe ich ganz einfach daten versenden kann, die sich selbst darum kümmert das alles klappt.

Siehe folgende Skizze:

[/URL]

Jetzt ist mit aber aufgefallend das die funktionen recv() bzw send() nur einen
(char) buffer als datentyp annehmen >_<

Wie könnte ich trotzdem folgende struktur über diesen weg versenden ?
Quellcode:struct Packet
{
     char data[512]; // Die eigntlichen daten
     unsigned char MessageTyp; // Welcher art die daten in "data" sind
     DWORD PacketNumber;  // Packet nummer / ID
     DWORD x,y,z;
     double offset;
}msg;
wie kann ich meine structur jetzt zu nem char* machen (und das dann am anderen ende auch wieder rückgänig machen ??)

--


Dieser Beitrag wurde am 26.03.2007 um 13:40 von Felheart bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
001
26.03.2007, 14:01
hausi



Zumindest unter Linux nimmt send einen untypisierten Pointer sowie eine Länge:
Quellcode:ssize_t send(int s, const void *buf, size_t len, int flags); Ich gehe mal davon aus, dass unter Windows auch eine Länge angenommen wird (alles andere würde nicht viel Sinn machen), also einfach auf char* casten:
Quellcode:ssize_t sent = send(socket, (char*)&my_packet, sizeOf(my_packet), 0); Und beim empfangen:
Quellcode:Packet my_packet;
ssize_t received = recv(socket, (char*)&my_packet, sizeOf(my_packet), 0);
Meine C/C++-Kentnisse sind halt schon ein bisschen eingerostet (so ungefähr 5 Jahre nix mehr damit gemacht), sollte aber ungefähr so gehen...

--


Dieser Beitrag wurde am 26.03.2007 um 14:01 von hausi bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
002
26.03.2007, 16:38
Felheart



Quellcode:ssize_t sent = send(socket, (char*)&my_packet, sizeOf(my_packet), 0);
Tut das nicht einfach blos die adresse von diesem array verschicken ??

wenn ich die '&' nach dem cast weglasse:

error C2440: 'Typumwandlung': 'Struct_Packet' kann nicht in 'char *' konvertiert werden

Ich hab das mal getestet. Das geht bei mir nicht >_<

edit:

ausserdem müsste man doch beim empfangen das bekommene (char*) in ein Struct_Packet casten !?

Egal, bei mir lässt sich weder Struct_Packet zu (char*) casten noch andersherum :(

edit2:

mit Struct_Packet mein ich die definition aus Post #000 ^^
das "Struct_" am anfang soll nur deutlich machen worum es sich handelt ^^"

--


Dieser Beitrag wurde am 26.03.2007 um 16:43 von Felheart bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
003
26.03.2007, 17:06
theDon



Zitat:
Felheart postete
Quellcode:ssize_t sent = send(socket, (char*)&my_packet, sizeOf(my_packet), 0);
Tut das nicht einfach blos die adresse von diesem array verschicken ??
Nein.

--

\o tanz den naziprau! o/

And more than ever, I hope to never fall,
Where enough is not the same it was before

zum Seitenanfang zum Seitenende Profil || Suche
004
26.03.2007, 17:13
Felheart



Ok, dann bin ich zu doof oO

Kannste mir das bitte erklären ?
Ich seh' das so

..., (char*) (&packet), ...
..........|............|
...,(cast) (adresse des packets), ....

also die addresse vom packet wird als char* versendet
oder wie ?

edit:
auf jedenfall funktioniert es nicht.
wenn ich bei meiner "send_it(Packet MSG);"

vor das eigentliche senden ein:
"printf("Sending (char*): %s \n", (char*)&MSG);"
setze. krieg ich nur den ASCII smylie zu sehen also das erste symbol.

und so wird das dann auch übertragen!

am anderen ende (beim server er einfach das empfangene ausgiebt)
wird mir auch blos dieses symbol angezeigt :(

--


Dieser Beitrag wurde am 26.03.2007 um 18:23 von Felheart bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
005
26.03.2007, 18:14
Kriz



Die Adresse von my_packet wird benötigt, damit die Funktion den übergebenen Zeiger wieder dereferenzieren kann. Mit sizeof(my_packet) wird der Funktion die Größe der Struktur insgesamt in Byte übergeben. Die ist meistens größer als der tatsächliche Dateninhalt in Bytes -> Byte-Alignment.

Ich gehe mal davon aus, daß der normale Bytestreaming Prozeß angewendet wird: Der übergebene Zeiger wird dereferenziert und zwar als char* Array (daher denke ich, ist das explizite Casten des Zeigers nach char* in der Parameterliste auch nicht unbedingt nötig). Dann eiert eine for-Schleife von 0 < sizeof()-Wert das char* Array durch und jagt alle Bytes einzelnd in einem Schub (oder gepuffert, je nachdem) an den angegebenen Socket.

Korrigiert mich, wenn ich falsch liegen sollte.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
006
26.03.2007, 19:13
Felheart



und wie krieg ich jetzt meine struct durchs Ethernet gedrückt ?

kann ich die struct ned irgenwie anders in ein anders format bringen ?
wie geht das z.B. bei CS ? oder Bittorent ?

--


Dieser Beitrag wurde am 26.03.2007 um 19:14 von Felheart bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
007
26.03.2007, 20:41
feigling



recv(socket, (char*)&my_packet, sizeOf(my_packet), 0)

wäre jetzt meine Idee, wobei ich noch nen versucht habe nen struct zu versenden.

Warum guckst du dir nicht einfach mal den Code von Bittorent oder von anderen Programmen an (die natürlich in C geschrieben sein müssen, sonst ists etwas witzlos), um zu sehen, wie es da gemacht wird?

--


Dieser Beitrag wurde am 26.03.2007 um 20:43 von feigling bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
008
26.03.2007, 22:00
Kriz



@Felheart: Du hast es immernoch nicht verstanden, oder? Ich empfehle dir mal dringend ein C/C++ Tutorial zulesen oder ein entsprechendes Fachbuch zu kaufen. Dir fehlen die Grundlagen, wie C/C++ Daten intern organisieren und wie man diese "low level" mäßig verarbeiten kann. Im Schnelldurchgang: Deine Struktur wird von der Funktion in ein char-Array umgewandelt, damit C/C++ die Struktur byteweise (weil idealerweise ein char ein Byte groß ist) verarbeiten kann. Dieses char Array wird nun als Bytestream über den Socket gejagt und meinetwegen irgendwann als TCP Pakete zum Receiver. Dort muß die entsprechende Gegenfunktion aus dem empfangenen char Array (Bytestream) wieder deine Struktur herzaubern. Das macht sie so, indem sie soviele Bytes aus dem Stream nacheinander von vorne wieder in die leere Strukturhülle reinschiebt, bis sie voll ist. Und wenn du danach wieder einzelnd auf die Strukturelemente zugreifst, sind hokuspokus die Daten dort drin. Die Details bitte aus Tutorien usw. entnehmen. Das war jetzt nämlich wirklich ein sehr oberflächlicher Schnelldurchgang...

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
009
27.03.2007, 12:49
Felheart



Ok, danke.

Werd's versuchen. Bei nem' erfolg meld ich mich :)

--

zum Seitenanfang zum Seitenende Profil || Suche
010
27.03.2007, 13:28
Felheart



Post editieren geht nicht mehr also sry für 2xPost!

@kriz: ich brauch kein buch ich weis was du meinst :D
hast es gut erklärt xD

um die ganze sache jetzt mal aufzuklären:
nach hausi's post habe ich das was er meinte auch gleich probiert.

Leider kam beim server die falsche nachricht an, das lag aber nicht am code
den er / feigling posteten, sondern an einem leichtsinns-fehler beim
datenaustausch zwischen dem SR_Thread und der Queue / List.

Danke nochmal

--

zum Seitenanfang zum Seitenende Profil || Suche
011
27.03.2007, 14:04
hausi



Zitat:
Felheart postete
@kriz: ich brauch kein buch ich weis was du meinst :D
hast es gut erklärt xD
Ich glaube schon, dass du das brauchst. Vielleicht nicht für dieses Problem, vielleicht auch nicht für das nächste, allerdings kann ein gutes Buch nie schaden. Wenn du dafür kein Geld ausgeben willst, findest du sicher auch eines bei wikibooks.org oder so (keine Ahnung, wie gut dass das eben verlinkte ist).

--

zum Seitenanfang zum Seitenende Profil || Suche
012
27.03.2007, 16:48
oxff



Ich gehe mal davon aus, dass du TCP benutzt. Dann ist das direkte Lesen in eine Struct eine verdammt schlechte Idee, denn durch Segmentierung können zwischen 1 und sizeof(myStruct) bytes auf einmal gelesen werden. Du müsstest dann entweder hässlich loopen:

Quellcode:int received = 0;
struct myStruct buffer;

do
{
  int r = recv(sk, ((char *) &buffer) + received, sizeof(buffer) - received, 0);

  if(r <= 0)
    break;

  received += r;
} while(received < sizeof(buffer));
Oder du implementierst das direkt mit ordentlichem Buffering.

Structs zu versenden ist eh eine Scheissidee, weil das nur klappt, wenn beide Boxen die gleiche byteorder haben.

--

mwcollect - mein Projekt | oxlog - mein blog | happyhardcore.com Stream - gute Musik

zum Seitenanfang zum Seitenende Profil || Suche