Multithreadovy TCP server

Programovacie jazyky, rady, poradňa...
metthal
Guru wannabe
Guru wannabe
Používateľov profilový obrázok
Príspevky: 2475
Registrovaný: 26 jan 2006, 18:32
Bydlisko: Nitra / Brno

Multithreadovy TCP server

Príspevok od používateľa metthal »

Zdravim,

no takze len v ramci vlastnej zvedavosti a precvicenia si prace s threadami a socketmi som sa rozhodol ze si spravim taky mensi TCP server, ktory este neviem presne naco pouzijem, ale chcel by som proste aby dokazal drzat spojenie s viacerimi klientami cize musim do toho zapojit multithreading. Na komunikaciu pouzivam kniznicu WinSock2 a process.h na threading (C++)

Kedze v tejto oblasti nemam az tolko skusenost, chcel by som sa spytat ci na to zatial idem dobre. Tu je postup ako to robim:

1. Spusti sa aplikacia a inicializuje sa WinSock cez WSAStartup, posledna funkcia ktoru volam predtym ako prejdem do dalsieho thredu je listen(listenSocket, 10)
2. Vytvori sa nove vlakno, v ktorom bezi cyklus while(!closing) accept(...) tj snazim sa vytvorit socket ktory drzi spojenie server-client
3. Pri uspesnom vytvoreni socketu, ho hodim do zoznamu.
4. Zavtedy bezi hlavny thread, v ktorom je cyklus ze dokedy nenapisem "exit" tak program stale bezi.
5. Akonahle napisem "exit", nastavi sa closing na true, tym padom skonci listener, ten ukonci svoj thread, ja zavtedy cakam v hlavnom vlakne kym toto listener vlakno skonci a ukoncim program

Neviem vsak, ako presne tam mam zakomponovat prijmanie dat. Mam vytvorit pre kazdy novy socket nove vlakno? To mi nepride ako vhodne, pokial tam budem mat pripojenu napriklad stovku klientov. Nebude to nanho vela? Neviem ma proste napadnut akym sposobom vyriesit citanie dat.

//autoeditácia príspevku (06 Júl 2012, 16:55)
Nasiel som si teraz nieco o tzv Concurrent modele, kde sa vyuziva select(), ktory skuma zmenu na socketoch, teoreticky by to slo aj takto, ale co ak chcem proste model, kde automaticky ako nieco pride, tak to spracujem. Nechcem sa spoliehat na ticky servera a spracovavat to po nich. Akoze ked mi uz nic ine neostane, tak spravim aj to.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8223
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Multithreadovy TCP server

Príspevok od používateľa harrison314 »

To ako to ma byt riesene dost zalezi od charkteru spojenia ( dlzka, systemove zdroje potrebne na obsluhu).
Vo vseobenosti sa to riesi tak, ze mas rad ( qeueu ) do ktoreho v hlavnom vlakne strkas poziadavky, v tvojom pripade otvorenu komunikaciu, a potom mas vlakna ( casto premenlivy pocet ale z obmedzenim maximalneho poctu), ktore z radu vyberaju poziadavky a spracovavaju ich.
metthal
Guru wannabe
Guru wannabe
Používateľov profilový obrázok
Príspevky: 2475
Registrovaný: 26 jan 2006, 18:32
Bydlisko: Nitra / Brno

Re: Multithreadovy TCP server

Príspevok od používateľa metthal »

No dobre, takze ak som spravne pochopil. Mam spravit queue, do ktorej budem zapisovat sockety z ktorych treba nieco precitat alebo zapisat (to by som uz rozoznal nejakym flagom). A teraz proste po kazdom volani select() zobrat tie rozdelit tuto queue medzi max N threadov, ktore by stale vznikali a zanikali. Problem mi tam mozno len moze robit to, ze aby mi select() nevratil socket, na ktorom sa uz nieco vykonava, potom by sa mohlo stat ze 2 thready sa budu snazit pracovat na rovnakom sockete. Mozno predtym ako sa vykona select() by som mohol vyhodit file descriptor z file descriptor setu, aby ten socket neprehladavalo. Co ty na to? Mas nejake napady?
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8223
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Multithreadovy TCP server

Príspevok od používateľa harrison314 »

V tom co som pisal je lepsie pouzit while(!closing) accept(...) , toto je vohne name na stredne dlhe spojenia a nemoze sa ty stat ze na tom istom sokete ty budu pracovat dve vlakna.

Ono je to klasicka ukazka pouzitia modelu producenti-konzumenti.
metthal
Guru wannabe
Guru wannabe
Používateľov profilový obrázok
Príspevky: 2475
Registrovaný: 26 jan 2006, 18:32
Bydlisko: Nitra / Brno

Re: Multithreadovy TCP server

Príspevok od používateľa metthal »

No momentalne som si vsimol tvoju reakciu. Uz to mam rozpracovane na metode select(), pouzivam sockety v non-blocking mode, mam socket zabaleny v triede Connection, kde mam readBuffer a writeBuffer. Predtym ako vsak zavolam select() na file descriptory, tak prechadzam spojenia a vsetko co ma plny readBuffer vyhadzujem z file descriptor setu na citanie a vsetko co ma prazdny writeBuffer vyhadzujem z file descriptor setu na odosielanie. Myslim ze teraz by mi uz len stacilo pridat do tej triedy Connection, nejaky bool, popripade handle s threadom, ktory obsluhuje dany Connection a ak by uz nejaky socket bol obsluhovany tak ho vyhodim tiez z file descriptor setu.

Co myslis? Fungovalo by to? Su to len moje teoreticke zvasty, je mozne ze to ani nebudem vediet spravit tak ako to opisujem. Prinajhorsom sa vratim k blocking modelu a accept()-u avsak s tym sa mi najhorsie pracovalo. Ked tak je tu moznost este async model, lenze tento model ma len Windows, ak by chcem svoj server rozsirit o moznost bezat na linuxovej masine, tak POSIX sockety nemaju nic ako async model a musel by som aj tak robit na cisto non-blocking modele.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8223
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Multithreadovy TCP server

Príspevok od používateľa harrison314 »

To ci by to bude fungovat si musis vyskusat sam, lebo som este nerobil so select, ja som robil len z modelom co som ty napisal a bezal mi natom mikro HTTP server. A este som pouzival asichronne API pre dotnet pre UDP ( SIP proxi server ).
Napísať odpoveď