NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: TcpClient<>TcpListener komunikace

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Erik Šťastný:27.9.2016 16:52

Zdravím, pracuji na client - server aplikaci a pro komunikaci používám normálně stringy dekódované na byte[] a ty posílám, nicméně bych se rád zeptal co použít pro přenos jednoduchých řídících signálů. jako např, že se má prostě jen na serveru spustit jedna metoda atp.

Mám prostě posílat přes to spojení např jedno zakódované int číslo? Prakticky mi na strašně serveru staří obdržet "číslo třeba 0-255" a na to si můžu nastavit 256 různých reakcí, ale zajímá mě jestli je to v pořádku řešení nebo je nějaké mnohem lepší a přitom není o moc těžší :)

Díky moc! :)

 
Odpovědět
27.9.2016 16:52
Avatar
Odpovídá na Erik Šťastný
Neaktivní uživatel:27.9.2016 17:15

Nevím jestli to není moc OOP overkill, ale já bych si vytvořil abstraktní třídu Message (která nic neobsahuje).
Z ní pak mohou dědit třídy jako ControlMessage nebo TextMessage, které budou obsahovat vhodné vlastnosti (jak říkáš číslo nebo text). Tyto třídy pak serializuješ ( Binární serializace vrací bajtové pole) a odešleš. Na straně příjemce poté deserializuješ do třídy Message, a uděláš rozhodovací logiku dle typu té Message:

if(message is ControlMessage)
...
else if(message is TextMessage)
...
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
27.9.2016 17:15
Neaktivní uživatelský účet
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Erik Šťastný
ostrozan:28.9.2016 6:11

Záleží na tom, jestli ta řídící informace je vázaná na ten konkrétní string.
Pak bych ji zakomponoval do něj - třeba hned jako první bajt a pak na straně příjmu switchem rozhodnout co s ním.
Pokud ale jsou řídící povely a data na sobě nezávislé, tak bych asi použil něco co popisuje Lukas

 
Nahoru Odpovědět
28.9.2016 6:11
Avatar
Odpovídá na Neaktivní uživatel
Erik Šťastný:29.9.2016 10:10

Jo oba co říkáte zní asi dobře :) Druhá otázka je jestli je todle řešení správné. Je v pořádku to řešit todle řízení a zároveň dotazy na server obyčejnýmy čísly?

Jednoduchý příklad server bude clientovi posílat aktuální datum když si ho client vyžádá. Jak by měl vypadat takový požadavek? Nejjednodušší mi prostě přijde, že client pošle jen třeba int číslo 1 a server bude v podmínkách vědět (if IncomingRequest == 1, tak poslat zpátky datum). Ale už na první pohled mi to nepřijde moc elegantní řešení zvlášť když bude mít server v řádech stovek funkcí.

 
Nahoru Odpovědět
29.9.2016 10:10
Avatar
Marian Benčat:29.9.2016 10:48

Je to zcela standardní řešení.. nemáš tam ale v kodu číslo ale prostě konstanty.. Máš prostě něco čemu se říká packet protocol a v něm máš takhle nadefinované jednotliví packety.. tam se ale pak řeší různé optimalizace, které jsou o binárních operacích atd atd.. ;-) Je to poměrně rozsáhlá látka.. které bych se ale možná v tvém případě prvoplánově nevěnoval a udělal to cestou nejmenšího odporu.

Nahoru Odpovědět
29.9.2016 10:48
Totalitní admini..
Avatar
Marian Benčat:29.9.2016 10:49

Za sebe ti můžu doporučit se kouknout třeba na eAthena server emulator.. je to emulator pro MMORPG hru, na kterem jsem spolupracoval a právě síťařinu a threading má opravdu na pěkné úrovni. Je to sice Céčko, ale pointu v tom najdeš.

Nahoru Odpovědět
29.9.2016 10:49
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:29.9.2016 12:26

Tak to, že je to standartní řešení mě celkem těší. Takže základní věci zredukuju na jednoduché integery a na větší záležitosti použiju serializaci třídy jak poradil kolega nahoře.

Hehe Ragnarok Online :) Threading na štěstí asi nebudu muset řešit, stačí mi vše synchronní a requesty odesílat jak za sebou přijdou :) Ale na tu síťařinu možná mrknul díky za tip :)

 
Nahoru Odpovědět
29.9.2016 12:26
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:30.9.2016 11:38

Aha tak kecám zjistil jsem, že vlákna budou potřeba pokud nebudu chtít po každé zprávě ukončovat spojení :D

 
Nahoru Odpovědět
30.9.2016 11:38
Avatar
Marian Benčat:30.9.2016 15:17

Pokdu to má být něco jako herní server, tak stejně budeš potřebovast connecitonless přístup :-) Ono není úplně ideální na long-term věci mít otevřeno 100 connectionu :-)

Nahoru Odpovědět
30.9.2016 15:17
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:30.9.2016 15:19

Co myslíš tím "connecitonless přístup" ? :)

 
Nahoru Odpovědět
30.9.2016 15:19
Avatar
Marian Benčat:30.9.2016 15:21

UDP například.

Nahoru Odpovědět
30.9.2016 15:21
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:30.9.2016 15:39

Hmm to bohužel nepůjde, neposílám nic vhodného na UDP, jinak říkáš, že je lepší když člověk potřebuje TCP, tak ty spojení radši uzavírat? :-O Já právě to zrovna přepisoval aby každý client měl spojení dokud se sám neodpojí a ne aby se co každých x zpráv dělalo nové :D

 
Nahoru Odpovědět
30.9.2016 15:39
Avatar
Odpovídá na Neaktivní uživatel
Erik Šťastný:3.10.2016 11:27

Nakonec jsem to udělal přesně jak říkáš, z počátku jsem se toho bál, ale předávat si hotové třídy je mnohokrát "hezčí" :)

Nicméně se potýkám s problémem deserializace na druhé straně která přijme serializovanou třídu.

Konkrétně jde o vyjímku:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: Sestavení ConsoleApplication3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null nebylo nalezeno.

Dočetl jsem se na netu, že je třeba aby měli projekty nějaké společné reference, a ne jen tu stejnou definici třídy, můžete mě prosím navést? :)

Editováno 3.10.2016 11:28
 
Nahoru Odpovědět
3.10.2016 11:27
Avatar
Marian Benčat:3.10.2016 12:28

K tomu, aby bylo možné tyto věci deserializovat, musíš mít assembly, kde je ten typ definovat s metadaty.

Ty definice těch zpráv dej do nějaké class library "Shared" nebo "Contracts". Na to si nareferencuj server a klienta.

Nahoru Odpovědět
3.10.2016 12:28
Totalitní admini..
Avatar
Erik Šťastný:3.10.2016 14:03

Jestli jsem tě správně pochopil, tak jen napíšu DLL třeba ve kterém budou definice všech objektů které budu chtít posílat a to DLL bude používat i server i client, ano? :)

 
Nahoru Odpovědět
3.10.2016 14:03
Avatar
Marian Benčat:3.10.2016 14:28

jo a priste reaguj.. at se mi ukaze notifikace.

Nahoru Odpovědět
3.10.2016 14:28
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:3.10.2016 14:32

vyjímečně jsem zapomněl :) jdu to testnout

 
Nahoru Odpovědět
3.10.2016 14:32
Avatar
Odpovídá na Marian Benčat
Erik Šťastný:3.10.2016 14:40

No dokonalost už to běží jak má a vesele si posílám structury :) Moc děkuji!! Bohužel druhé řešení ti nedám :)

ještě jen taková otážečka, myslíš, že je lepší poslat více menších tříd/struktur nebo jednu obrovskou? Hádám, že kvůli TCP je lepší poslat rovnou jednu větší, ne?

 
Nahoru Odpovědět
3.10.2016 14:40
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 18 zpráv z 18.