send() strings werden vermengt??
-
ich sende relativ schnell mit dem server nachrichten an den client. die nachrichten sind so aufgebaut:
(beispiel)
000@004@NAMEtext
000 steh für normale textnachricht, 004 für die länge des namens...nun passiert manchmal folgendes:
Konnte zu 127.0.0.1 verbinden [SERVER]: Name ist bereits vergeben!000@006@SERVERKein Username angegeben(Verbindung getrennt) Connection Error Konnte zu 127.0.0.1 verbinden [SERVER]: Name ist bereits vergeben! [SERVER]: Kein Username angegeben(Verbindung getrennt) Connection Errorbei der ersten trennung wurden zwei nachrichten scheibar zusammen empfangen und so konnte die zweite nicht richtig interpretiert werden.. oO das ist nicht nur ärgerlich sondern ein problem...wie kann ich sowas verhindern?
-
recv() empfängt einen Bytestrom, der von send() gesendet wird. Unterschiedliche send()-Aufrufe ergeben trotzdem nur einen großen Bytestrom.
Deswegen musst du selbst dafür sorgen, dass dein Programm das Ende einer Nachricht erkennt.
-
echt? aua dann mussich aber ne menge ändern oO
bzw womit kann man denn das ende einer nachricht markieren?
-
hallo Pixartist.
Mache das ganze in einer Struktur.
also so ungefähr:typedef struct tagNETWORKPACKET { unsigned short int Type; //Hierfür kannste deine eigenen Konstanten definieren unsigned short int DataSize; //hier ist die Anzahl der BYTES in [Data] die beachtet werden müssen. BYTE Data[4096-(2*sizeof(unsigned short int))]; } NETWORKPACKET;Deine datenpakete ahben dann IMMER eine fixe Größe von 4KB und du weist wie viel du mit recv() einlesen musst

Sicher kannst du die Struktur ja noch deinen Bedürfnissen anpassen..
Und hier die Antworten auf paar Anfängerfragen die ich mir stellte als ich zum ersten mal strukturen versenden wollte:
1.Wie kann man ne Struktur send() übergeben und senden?
- Ganz einfach bei send als datasource die Adresse der Struktur übergeben und weil diese so allein nciht akzeptiert wird (send will ja char*) einfach casten mit:(LPBYTE)&DataPacket2.Wie kann man ne Struktur einlesen mit recv()?
- Auch ganz einfach. Einfach eine Struktur des typs NETWORKPACKET erstellen und recv() als Größesizeof(NETWORKPACKET)übergebn und als destination die adresse der erstellten Instanz der Struktur NETWORKPACKET.
MfG Tolga.
-
oO das hab ich jetzt nich ganz durchblickt..da muss ich mal mit beschäftigen. willst du sagen das man statt chars auch ganze objekte(instanzen) übergeben kann?
typedef struct tagNETWORKPACKET { unsigned short int Type; //Hierfür kannste deine eigenen Konstanten definieren unsigned short int DataSize; //hier ist die Anzahl der BYTES in [Data] die beachtet werden müssen. BYTE Data[4096-(2*sizeof(unsigned short int))]; } NETWORKPACKET;was mach ich jetzt genau hiermit? ich habs leider nicht ganz verstanden
muss ich bei rcv als grösse sizeof(NETWORKPACKET) angben...und sonst noch? ich muss doch dann auch bei versenden immer genau 4kb verschicken? und was heisst jetzt BYTE Data[4096-(2*sizeof(unsigned short int))]; genau?
fragen über fragen
ich glaub am besten würd ichs kapieren wenn du beispielshalber was einefaches versendest und wieder empfängst...mit einer spezifizierten grösse!PS: WAS genau muss ich IN einee struktur machen?
-
pixartist schrieb:
typedef struct tagNETWORKPACKET { unsigned short int Type; //Hierfür kannste deine eigenen Konstanten definieren unsigned short int DataSize; //hier ist die Anzahl der BYTES in [Data] die beachtet werden müssen. BYTE Data[4096-(2*sizeof(unsigned short int))]; } NETWORKPACKET;WAS genau muss ich IN einee struktur machen?
habe ich doch schon erklärt..
die struktur hat 3 elemente.
Type, DataSize und Data. data enthälr deine Daten. In datasize steht anzahl der bytes die der Remote -wenn er die struktur mit recv() einliest- verarbeitet. Somit hat sihc das Problem mitm trennzeichen erledigt. Denn in DataSize steht ja wo ende ist. Wenn DataSize 223 ist dass ist beim 223. Byte Ende!In Type stehn dann die konstanten:
z.b.
//Data-Type Constants... #define DT_DATA 0 #define DT_ABORT 1 #define DT_INFO 2 #define DT_SYSTEMCOMMAND 3 bla.. bla.. bla.... usw.Und Dein Server erhält dann die Struktur und sieht in nach was für daten sich in data befinden und jenachdem verarbeitet er diese daten. Mit DT_DATA kannste z.b. chat-text senden. Mit DT_SYSTEMCOMMAND sonderbefehle, die für technische Kommunikation zwischen Client und Server stattfindet...
Damit hast du den Mist mit den Trennzeichen nciht mehr zu bewältigen.
PS: Sicher kann man strukturen senden da diese nichts als Speicherberecihe sind die byteweise über einen Pointer engelesen werden.
Aus Erfahrung kann ich sagen, bei Netzwerkanwendungen sind Strukturen das aller Beste. (Meine persönliche Meinung)
-
Wäre es nicht besser, wenn man erst die Größe der Struktur sendet und dannach die Struktur? Dann verschwendet man nicht soviel Bandbreite.
-
Ich schlage folgendes vor:
struct Packet { unsigned crc32; //crc des ganzen Packets, beginned mit dem size Member unsigned size; //Größe von pData; //BYTE pData[size]; };
-
Warum ist pData auskommentiert? Hat das irgendwas zu bedeuten?

-
uff so ich pack nicht wie man structs verwendet!
folgende vorraussetzung:string buffer = "das willich versenden"; int i = 10; //und das auch //und zwar mit einem einzigen send! //beim rcv möchte ich dann jeweils die daten wieder in eigene variablen tun! //ich würde mich freuen wenn mir wer n kurzes beisp dazu amchen könnte DANKE! :) send(s,???,???,0); /* ... */ ??? = recv(s);danke
-
Das kommt davon wenn man sich ständig weigert, endlich mal C/C++-Grundlagen zu erlernen.
Spätestens jetzt siehst Du, was Du davon hast...

-
hihi schrieb:
Warum ist pData auskommentiert? Hat das irgendwas zu bedeuten?

Das liegt daran, dass pData eine variable Größe hat und der Speicher dafür außerhalb der Struktur reserviert wird. Der Vorteil vom Ganzen ist, dass man jedes Mal den Header einlesen kann, (die Packet struct) und danach folgen die eigentlichen Daten (pData)

-
Hepi schrieb:
Das kommt davon wenn man sich ständig weigert, endlich mal C/C++-Grundlagen zu erlernen.
Spätestens jetzt siehst Du, was Du davon hast...


-
jo geile antwort...ich weiss zwar nicht was das versenden von strukturen mit winsock mit grundlagen am hut hat, aber deine antwort hat mich richtig weitergebracht...
-
pixartist schrieb:
jo geile antwort...ich weiss zwar nicht was das versenden von strukturen mit winsock mit grundlagen am hut hat, aber deine antwort hat mich richtig weitergebracht...
Naja... send() hat von der Logik her viel mit fwrite() (eine Standard-C-Funktion) gemeinsam. Du kannst damit eben nicht nur Textstrings, sondern beliebige Bytes verschicken.
Evtl. musst du die struct erst in einen solchen Bytestrom umwandeln (Stichwort casten).
-
also per (long)variable
edit: hab mich mal beim msdn nach structs erkundigt..komme langsam dahinter
edit2: ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhtypedef struct tagNETWORKPACKET { unsigned short int Type; //Hierfür kannste deine eigenen Konstanten definieren unsigned short int DataSize; //hier ist die Anzahl der BYTES in [Data] die beachtet werden müssen. BYTE Data[4096-(2*sizeof(unsigned short int))]; } NETWORKPACKET;JETZT kapier ich was du da machst oO mensch das kann man aber auch einfacher erklähren ^^
-
wie komm ich denn auf const *char? mit LPBYTE krieg ich ja unsigned *char
-
Vielleicht LPCSTR

-
pixartist schrieb:
wie komm ich denn auf const *char? mit LPBYTE krieg ich ja unsigned *char
(LPBYTE) wird von recv() und send() akzeptiert und mit Erfolg verarbeitet!
Du solltest BYTES und keine chars senden. Bei manchen Compilers ist char als signed char definiert. Dann hast du evtl. Probleme. Du musst entweder unsigned char oder gleich BYTE benutzen.BYTE ist folgenderweise definiert:
#define BYTE unsigned charAuf das 'unsigned' kommts an.
Deswegen solltest du nciht nach (const char*) sondern nach (LPBYTE) oder nach (const unsigned char*) casten.
-
D:\Programme\C++ files\MSDev98\MyProjects\WinSockets\WinSockClient\main.cpp(150) : error C2664: 'send' : Konvertierung des Parameters 2 von 'unsigned char *' in 'const char *' nicht moeglichmist ich kann als destination nicht die adresse von der struktur angeben! rcv gibt immer nen char zurück!
ich kann aber auch keinen char in ne struct casten