Když chyba není mezi židlí a klávesnicí

Poctivé programování síťových aplikací není žádná sranda. V principu se jedná o asynchronní komunikaci, takže pro napsání kvalitní aplikace se člověk nevyhne použití vláken a s tím související synchronizace a podobných radostí. Ladění takové aplikace pak není vůbec žádná sranda a když se vyskytne nějaký problém, tak se člověk pěkně zapotí, než ho lokalizuje a vyřeší.

Protože dělám na serveru pro jednu úspěšnou MMORPG (ne, není to WoW 😉 ), tak jsem se musel pořádně ponořit do síťového programování a narazil jsem hned na dva problémy, u kterých jsem nakonec zjistil, že nejsou způsobeny mnou.
První zajímavou vlastností je to, že když se uzavře TCP socket, tak první zpráva odeslaná po jeho uzavření je WinAPI interpretována jako úspěšně doručená – až druhou odeslanou zprávu se nepodaří doručit. Nejzajímavější na tom je, že se jedná skutečně o problém ve WinAPI, protože např. ve Wiresharku je vidět, že zpráva nebyla potvrzena.
Druhý problém je o úroveň výše – v .NET Frameworku. Pro obsloužení velkého množství klientů používám metodu System.Net.Sockets.Socket.Select, která bere jako poslední parametr hodnotu time-outu. Podle nápovědy, pokud chceme nekonečný time-out (tedy dokud se něco nestane), tak bychom měli jako parametr dát -1. Toto ale nefunguje. Po prohlédnutí Reflectorem jsem zjistil, že s hodnotou -1 parametru microSeconds se nikde nepracuje a hodnota tohoto parametru se vždy tupě převede na strukturu, která je vhodná k P/Invoke volání metody select z WinAPI. V nápovědě k této funkci se pak můžeme dočíst, že pro zadání nekonečného time-outu (tedy blokujícího volání) je třeba předat místo ukazatele na strukturu TIMEVAL hodnotu null. Toto se ale v implementaci metody System.Net.Sockets.Socket.Select nikde neděje, takže nezbývalo než napsat si vlastní wrapper pro funkci select. To nebylo nic extra složitého a můžete tahat zde.
Nekonečný time-out jsem nakonec ale nepoužil, aby server dokázal v rozumném čase reagovat na nová připojení, ale byl to pro mě další důkaz toho, že co si člověk sám neudělá, to pořádně nemá 😀

Zanechat odpověď

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

Logo WordPress.com

Komentujete pomocí vašeho WordPress.com účtu. Odhlásit /  Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Odhlásit /  Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Odhlásit /  Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Odhlásit /  Změnit )

Připojování k %s

Tento web používá Akismet na redukci spamu. Zjistěte více o tom, jak jsou data z komentářů zpracovávána.