Diskuze: C# TCP server někdy odešle zprávu se zbytky předchozí zprávy
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 14 zpráv z 14.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj. Problem je v tom, ze jedna tvoja odoslana sprava moze byt zabalena do viacerych TCP paketov, preto pri citani dostavas neuplne casti. Na .Net urovni je najefektivnesie (ak nie aj jedine) riesenie posielat si nejaky START pripadne STOP znak (skupinu znakov). Potom jednoducho cyklicky citas a spravy si rozdelujes podla tychto znakov (vies ze si ju precital celu).
Zasekl jsi se na stejném problému, který mě děsně trápil když jsem
já poprvé začal s TCP
Je to přesně jak píše Jahnny nademnou.
Read ani write ti vůbec negarantuje, že pošleš nebo přečteš přesně ten
počet bytů co chceš. Je třeba to například číst opakovaně dokud
nebudeš spokojený.
Možnost je například jak píše Jahnny, ale je jich víc.
Já například si implementovat to, že se vždy pošlou 4 bajty které
obsahují integer kolik dalších bajtů je zpráva kterou musím
přečíst.
Tady máš přesně topic ve kterém jsem se na to ptal Můžeš si to pročíst.
Děkuji mockrát za odpověď
Momentálně mám systém vyřešený tak, že každou zprávu končím znakem "!". Poté tu zprávu rozdělím právě tímto znakem, přidám si je do listu a jednu po druhé je vyhodnocuji. Zprávy, které nemají správný formát ignoruji. A jako pojistku mám v Arduinu kód, který když do nějaké doby neobdrží odpověď tak zprávu pošle znova.
Zatím to vypadá, že vše šlape tak jak má. Uvidíme jak se to bude
chovat když k tomu přidáme pomalejší a méně stabilní připojení
U TCP by se ti určitě nemělo nikdy stát, že nějaká zpráva nepřijde.
To by znamenalo chybu celého spojení a nutnost jeho znovu vytvoření, nikoliv
jen znovu odeslání zprávy.
No ta záloha je tam hlavně z toho důvodu, kdyby nějaká zpráva přišla neuplná. (Například jedna čast by došla na konci Bufferu a druhá část na začátku nového bufferu)
Ty by jsi to ale ideálně měl udělat tak, že ten buffer budeš skládat
až dokud nenarazíš na ten tvůj "!" až pak tu zprávu zpracovat Takto pokud chápu správně, tam
přidáváš haldu zbytečného provozu.
Oddelovat vykricnikem fungovat muze, pokud se posilaji jen jednoduche stringy, ktere vykricnik obsahovat nemuzou, ale idealni a bezne pouzivane reseni je (jak uz tu bylo zmineno) posilat nejaky header, kde je uvedena delka a typ zpravy a pak cekat, az se precte cela zprava.
Nad tím už jsem přemýšlel. Napadlo mě, že bych po naplnění bufferu mohl ten buffer uložit do stringu. String pak rozdělit vykřičníkem, odebrat z něj uplné zprávy, zbytek v něm nechat a následně k tomu zbytku přidat obsah dalšího bufferu. Akorát si momentálně nějsem jistý jak udělat tu část "odebrat ze stringu".
No do budoucna určitě přemýšlím nad tím to udělat tímto způsobem, zvlášť když budu do té aplikace přidávat další funkce, ale momentálně to asi plánuju nechat takto. Přece jenom ty stringy které jsou odesílané jsou docela jednoduché a nemají moc variací.
Něco takového asi můžeš. Zkrátka zacykly ten read na tak dlouho, dokud
nebudeš mít i ten vykřičník
Nicméně lepší je podle mě jak píše Luboš, udělat si ty hlavičky. Pak přesně víš kolik bajtů máš přečíst a neřešíš to až podle dat obsažených v bajtech.
Zobrazeno 14 zpráv z 14.