Avatar billede Droa Seniormester
21. maj 2015 - 20:08 Der er 11 kommentarer og
1 løsning

Netværks server med multi socket funktion

Hej eksperter.

Jeg sidder og vil lave en Multisocket server, dog har jeg svært ved og finde et ordenligt design.


min ide er og starte med 1 tråd til og acceptere nye sockets (listener socket)

---

Jeg gemmer derefter alle sockets i en trådsikret arrayliste, der også har session data på klienten (brugernavn, login dato, m.m)

hver gang listener tråden får et nyt opkald, add'er den så den nye socket til den trådsikret liste.


----

derfra bliver det så lidt et stort spørgsmålstegn for mig. min ide var at oprette en tråd for hver forbundet socket, hvor den læser i et evigt loop.

så hvis der er 20 klienter forbundet, er der 20 tråede der står og buldre løs i baggrunden.

----

alle reader trådende skriver så til en "queue" liste, hvor alle responses bliver skrevet til. (svar fra serveren)

----

en enkelt tråd behandler all svar fra "queue" listen, ved og skrive til den korrekte socket.

----

jeg vil trådsikre et List item,ved og bruge "block" på selve listen, og et manualresetevent i hver item i listen, der fortæller om dette item har en anden der læser fra det.

----

jeg regner med og bruge NetworkStream til både at læse og skrive fra.




mit spørgsmål er om dette er en god ide, eller om jeg skal forbedre mit design?

er networkstream trådsikret? kan man både læse og skrive med networkstream på samme tid, eller skal man sikre sige at dette ikke sker? (ManualResetEvent isWriting, ManualResetEvent isReading)

er der eventuelt en bedre måde at tråde is Reader? jeg er lidt bange for at en reader blocker, og serveren ikke længere modtager data fra andre klienter, før en socket  giver timeout.

ideer er velkomen.
Avatar billede arne_v Ekspert
21. maj 2015 - 20:19 #1
En traad per klient og blocking reads giver normalt en nem letlaeselig kode.

Og det fungerer fint op til et vist antal klienter. 500 eller 1000 eller noget andet - afhaengig af server.

Alternativerne er:

* non-blocking reads som finde i to varianter
    - check om der er noget i buffer
    - bede om at faa kaldt en metode naar der er noget i bufer

* skift fra TCP til UDP
Avatar billede Droa Seniormester
21. maj 2015 - 20:58 #2
nu er mit projekt målrettet til maks 100-200 klienter, så det er intet stort.
Generelt handler det bare om og blive bekendt med TCP multisocket design.

jeg har arbejdet meget lidt med non-blocking designs til udp, men tror jeg har misforstået konceptet, især fordi jeg bare tjekkede bufferstørrelsen, men jeg oplevede til at når jeg så læste dataerne, at den aligevel blockede, da den ikke var færdig med og modtage.

nu ved jeg ikke om tcp har samme problem, eller at den først har noget i bufferen, når den er klar til og modtage, så den ikke blokker længere end nødvendigt.

ville stadig gerne vide om man kan læse og skrive til en socket på samme tid, eller om man skal have traffiklys på (især igennem networkstream classen)? :)
Avatar billede arne_v Ekspert
21. maj 2015 - 23:15 #3
tcp vs udp og blocking vs non-blocking er uafhaengige af hinanden

Al default read er blocking, men .NET har gode muligheder for non-blocking via kald af metode naar der er noget.

Citat fra docs:

Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization. As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference between read and write threads and no synchronization is required.
Avatar billede Droa Seniormester
21. maj 2015 - 23:50 #4
perfekt, tror du svarede alle mine spørgsmål, jeg må have overset den beskrivelse, for mente jeg havde læst det hele, men jeg har stadig lidt besvær ved og navigere rundt på deres msdn, den virker meget rodet for mig, deres struktur giver ikke altid mening for mig :)

så jeg går ud fra jeg skal bruge DataAvailable til og tjekke for data? men mente der var en property man skulle sætte, for at den ikke blockede.
Avatar billede arne_v Ekspert
22. maj 2015 - 02:39 #5
DataAvailable er "check om der er noget i buffer".

Men der er ogsaa support for "bede om at faa kaldt en metode naar der er noget i bufer":

BeginRead
EndRead
Avatar billede j4k0b Nybegynder
22. maj 2015 - 10:57 #6
Ikke-blokerende reads kan godt give dig problemer, hvis du har 100-200 tråde (eller langt færre for den sags skyld).

Jeg har kun erfaringer med det i C og C++, og her går CPU'en totalt amok og bruger alt kraft den kan på at stå i løkker, som alligevel aldrig udfører noget.

Hvis du f.eks. har en tråd som læser fra en kø, som klienterne putter i, og tråden, som læser, skal afvikle kode periodisk, så lav endnu en Timer-tråd, der udelukkende laver blokerende sleep() og putter i køen når det er nødvendigt. På den måde får du udelukkende bygget dit program med blokerende kald, og derfor minimum CPU.
Avatar billede Droa Seniormester
22. maj 2015 - 15:09 #7
arne_v, så du siger at jeg skulle lave en tråd der looper igennem mit socket array, for og læse om der er nye data, hvorefter den så danner en sub-tråd, til og hente den nye data (hvis det nu er noget).

hmm det kunne være en ret god ide, så vil der kun være åbne tråde, når der var nye data, ville være ret scalerbar tror jeg.

jeg havde vist før tænkt på denne løsning, men jeg mener at jeg kom på et problem i designet, som jeg så helt har glemt nu, kunne være jeg skulle prøve igen, og se om det virker denne gang.

j4k0b, jeg regner ikke med og bruge ikke-blokkerende reads i et loops for hver en klient, det var kun hvis jeg brugte blokkerende reads, at jeg så det nødvendigt. ellers ville jeg havde brugt en løsning med mindre resolution.
Avatar billede arne_v Ekspert
22. maj 2015 - 18:45 #8
Ja. Eller brug den indbyggede BeginRead/EndRead mekanisme (som laver ca. det samme nede under motorhjelmen).
Avatar billede Droa Seniormester
22. maj 2015 - 18:54 #9
det regnede jeg os lidt med var det begin/end methoderne gjorde :) mange tak for de mange svar, lægger du et svar, så vi kan afslutte?
Avatar billede arne_v Ekspert
22. maj 2015 - 18:59 #10
svar
Avatar billede arne_v Ekspert
22. maj 2015 - 19:04 #11
Bemaerk at BeginRead/EndRead bruger IOCP saa den logik ligger dybt nede i operativ systemet og derfor maa formodes at vaere meget effektivt.
Avatar billede Droa Seniormester
22. maj 2015 - 19:10 #12
jeg fortrækker os at bruge de methoder, da de er ret simpelt lavet, ingen grund til og overveje 117 design problemer, når man har en all-in-one løsning.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB