[ YuMERA @ 29.06.2011. 11:35 ] @
Pozdrav...

Imam jednu client server aplikaciju u kojoj klienti kada pokrenu svoj softver automatski se vezu na server gde se indetifikuju i budu prihvaceni od strane servera... Server evidentira online kliente i prikazuje ih u ListView kontroli.

Moj "problem" bi bio u tome sto ne znam kako da prepoznam kada od strane klijenta socket bude nasilno prekinut (nestankom mreze ili nasilnim gasenjem kompjutera)... Kada klijent zatvori svoj program on se uredno odjavljuje i taj user vise nije online...

Treba mi neko prakticno resenje, ako naravno postoji, gde ne bi server dodatno opterecivao tako sto bi stalno sve usere proveravao dali su i dalje online i na taj nacin preterano trosio resurse.

Hvala
[ deerbeer @ 29.06.2011. 11:42 ] @
Citat:

Kada klijent zatvori svoj program on se uredno odjavljuje i taj user vise nije online..

Kako mislis da se klijent odjavi ako mu pre toga nestane mreza ili se ugasi kompjuter ?? :)
[ YuMERA @ 29.06.2011. 13:49 ] @
Pa ne mislim da moze da se odjavi ako nestane internet ili ugasi kompjuter a da pre toga nije zatvorio klijent aplikaciju. To i jeste ono sto mi treba kako da registrujem taj slucaj na serveru...

Kad izadje iz klijent aplikacije napravi u Form_Unload -> Winsock.Close i uredno se odjavi na serveru.
E sad meni treba neko prakticno resenje (koje nece trositi i dodatno opterecivati serverske resurse) samo za situaciju kad je prekinuta konekcija a da to nije serveru prijavljeno....

Radi se o serveru koji ima dosta klijenata online i prikazani su u ListView-u. Kad se klijent odjavi sa Winsock.Close onda server to registruje i izbrise ga iz ListView liste kao Online korisnika...
Dok god klijent ne zatvori tako komunikaciju, server ga drzi u listi kao online korisnika...

Mozda sam sad bio malo jasniji

[ deerbeer @ 29.06.2011. 14:14 ] @
Citat:

samo za situaciju kad je prekinuta konekcija a da to nije serveru prijavljeno...

Pa to moras na serveru da odradis .Ako klijent posalje neki regularan podatak sa socket.Send
to server prihvata sa socket.Receive . Ako u tom trenutku konekcija pukne taj Receive vrati 0 bytes received ili baci exception ,
znaci da je izgubio konekciju za klijentom i ti ga onda brises iz liste .


[ YuMERA @ 29.06.2011. 14:34 ] @
Citat:
deerbeer: Pa to moras na serveru da odradis .Ako klijent posalje neki regularan podatak sa socket.Send
to server prihvata sa socket.Receive . Ako u tom trenutku konekcija pukne taj Receive vrati 0 bytes received ili baci exception ,
znaci da je izgubio konekciju za klijentom i ti ga onda brises iz liste .


Hvala tebi prijatelju na pomoci ali to sto mi pokusavas objasniti ja vec znam. Verovatno se nismo najbolje razumeli sta meni u stvari treba......

Klijenti se konektuju na server indetifikuju se odredjenom zastitom i na osnovu toga imaju odredjene prioritete. E sad tu nezavrsava komunikacija server-klijent nego klijentske aplikacije posle indetifikacije, salju odredjene podatke koje server obradjuje, priprema i vraca klijentu... Znaci da je server non stop opterecen...

Meni ne treba programski kod nego neko idejno resenje kako bi resio problem nasilno prekinutu konekciju od strane klijenata a da sto manje sa tom proverom dodatno opterecujem server...

Razmisljao sam sa Timer objektom da recimo merim vreme neaktivnosti i da ih jednostavno brisem i iskljucim sa liste online korisnika....

Ili mozda ima neko bolju ideju...
[ Shon3i @ 30.06.2011. 08:26 ] @
Klijent nikako ne moze ispitati da li ce struja ili internet nestati i tik pre toga javiti serveru. Kao sto je rekao deerbeer, server je taj koji treba odnosno mora da ispituje. Ono sto meni pada napamet kao i kod mnogih drugih aplikacija je Timeout. Znaci ako prodje izvestan period da server odbaci komunikaciju sa klijentom.

Pozdrav
[ YuMERA @ 30.06.2011. 09:20 ] @
Hvala ti na pomoci....

Ali

ako nisi imao nista pametnije da kazes od ovoga :

Citat:
Shon3i: Klijent nikako ne moze ispitati da li ce struja ili internet nestati i tik pre toga javiti serveru. .......
Pozdrav


Onda bolje da nisi nista rekao jer ovakav savet pomalo vredja tudje znanje i intelegenciju....

p.s. Molim moderatore da obrisu temu jer ne vodi nikuda.... U medjuvremenu sam resio "problem" sa tajmer kontrolom sa kojom merim vreme od nekoliko minuta i ako neki od klijenata nema aktivnosti u datom periodu server aplikacija prekida komunikaciju i brise klijenta sa liste online korisnika...
[ deerbeer @ 30.06.2011. 09:32 ] @
Citat:

Onda bolje da nisi nista rekao jer ovakav savet pomalo vredja tudje znanje i intelegenciju....

Bolje ti je malko svoje znanje da preispitas .Covek nije mislio nista zlonamerno .

Citat:

ako neki od klijenata nema aktivnosti u datom periodu server aplikacija prekida komunikaciju

Sta tebi znaci prekida komunikaciju i sta ti znaci uopste komunikacija ?
Ti moras da znas ako koristis sokete i tcp protokol da tamo nema permanentne konekcije .
Klijent otvara soket na serveru salje nesto dobija nazad response i zatvara soket samim tim i "komunikaciju"(connectionless protokol ). Proguglaj malo o tome .
Tako da server na tom nivou nema pojma vise o tom klijentu osim sto mozes da zapamtis negde njegovu zadnju konekciju po ip adresi vremenu i na serveru meris (sto upravi u radis) kad je zadnji put ostvario konekciju .
Drugog resenja nema a ako ti TCP protokol ne odgovara u tvom scenariju i zelis permanentu vezu sa serverom koristi UDP protokol .
[ YuMERA @ 30.06.2011. 19:06 ] @
Citat:
deerbeer: Sta tebi znaci prekida komunikaciju i sta ti znaci uopste komunikacija ?

Vidi prijatelju da si procitao moj prvi post, kako treba, nebi sad dosli u sitauaciju da se prepiramo.
A sto se tice komunikacije ja sam mislio da bi to znacilo da dva kompjutera zapocinju komunikaciju tako sto uspostavljaju konekciju po odredjenom protokolu, vrse razmenu podataka i zavrsavaju je prekidom konekcije. Mislim (bar do sada sam mislio) da bi se tako nesto moglo nazvati komunikacija. Dve osobe isto mogu da komuniciraju tako sto se upoznaju (konektuju) dogovore se kojim ce jezikom da pricaju (protokol) i zapocinju razgovor (razmena podataka).
Bas me zanima sta ti smatras pod "komunikacijom"?

Citat:
Ti moras da znas ako koristis sokete i tcp protokol da tamo nema permanentne konekcije .
Klijent otvara soket na serveru salje nesto dobija nazad response i zatvara soket samim tim i "komunikaciju"(connectionless protokol ). Proguglaj malo o tome .
Drugog resenja nema a ako ti TCP protokol ne odgovara u tvom scenariju i zelis permanentu vezu sa serverom koristi UDP protokol .

Joj brate izgleda da ces morati ti malo da google-as. Socket se nezatvara sam od sebe. TCP protokol je bas taj koji uspostavlja permanentnu (virtualnu) konekciju a ne UDP.

Mozda je bolje slikovito objasnjavati :
Citat:
Protokol UDP (User Data Protocol), za razliku od protokola TCP, ne podrazumeva uspostavljanje stalne veze nego se paketi „bacaju“ odredišnom računaru, bez održavanja veze i provere grešaka.
Rad TCP protokola možemo zamisliti kao da na oba računara imamo „slavine“ za podatke i na te slavine povezujemo crevo i „puštamo“ podatke kroz to crevo da teku neprekidno, kao što bismo pustili vodu. S druge strane, slanje podataka kod UDP protokola liči na slanje poštom. Kao da se svaki paket stavlja u posebnu pošiljku, na koju se napiše adresa pošiljaoca i primaoca i zatim se ta pošiljka pošalje. Pri tome se uopšte ne zna kojim će putem pošiljka stići do svog odredišta, i neće se dobiti nikakva povratna informaciaj o tome da li je stigla na odredište.
Na taj način, ovaj protokol ne garantuje isporuku paketa niti isti redosled isporuke paketa kao pri slanju. Zbog ovih osobina UDP protokol je brz i koristi se za aplikacije kojima je važna brzina, a prispeće paketa i održavanje redosleda nije od velike važnosti. Budući da nema procedure sinhronizacije, dobija se na brzini, ali se gubi na pouzdanosti, nema kontrole toka ni zagušenja. Koristi ga veliki broj aplikacija, naročito aplikacije koje rade u realnom vremenu, poput Internet telefonije i video konferencije. Zgodan je za i za poslove u kojima treba slati manje količine podataka na veliki broj adresa. Koriste ga protokoli RTP, VoIP, DNS, serveri za računarske igre itd.

I nakraju samo tvoj citat :
Citat:
Bolje ti je malko svoje znanje da preispitas .Covek nije mislio nista zlonamerno .


[ deerbeer @ 30.06.2011. 19:44 ] @
Bravo , samo ti je dugo bilo potrebno da izguglas .
Happy coding !

[ captPicard @ 01.07.2011. 09:49 ] @
Koja prepotentnost.
[ YuMERA @ 01.07.2011. 10:14 ] @
Citat:
deerbeer: Bravo , samo ti je dugo bilo potrebno da izguglas .
Happy coding !


Sad postajes biti pomalo i bezobrazan...
Neznam zasto si se uopste javio da polemises o necemu za sta i sam nisi siguran da razumes najbolje....
[ deerbeer @ 01.07.2011. 10:25 ] @
Citat:

Neznam zasto si se uopste javio da polemises o necemu za sta i sam nisi siguran da razumes najbolje....

Ni ja ne znam zasto si postavljao temu kad vec sve znas !
[ YuMERA @ 01.07.2011. 16:07 ] @
Citat:
deerbeer: Ni ja ne znam zasto si postavljao temu kad vec sve znas !


Pa zato sto sam trazio idejno resenje. Ali ti nikako da procitas taj moj prvi post.

A obratio sam se ovde jer smatram da ovde ima izuzetnih ljudi, koji su profesionalci u ovom svemu i njihovo znanje i iskustvo nikad nebih pocenio...
Ali nazalost javio si se ti kao neko crkveno zvono da ovde zvonis bez povoda...
[ Marko_L @ 13.07.2011. 23:44 ] @
Verovatno se javljam malko kasno, ali šta je tu je. Elem, jedini pouzdan način da se utvrdi prisutnost klijenta na serveru jeste upravo da server vrši proveru svih klijenata i utvrdi da li neki nedostaje. To ne bi trebalo preterano da optereti server, jer je za proveru dovoljno poslati jedan ping i čekati odgovor, te ako tog odgovora nema u određenom roku, izbrisati klijenta sa liste. Naravno, radi dodatnog rasterećenja, ta provera se ne mora vršiti previše često, već može na svakih 5, 10, 30 sekundi ili čak više, zavisno već od realnih potreba, odnosno koliko je bitno da se lista klijenata osvežava što bliže realtime-u. Ovo sa merenjem neaktivnosti takođe može biti ok rešenje, ali i ne mora, što opet zavisi od vrste aplikacije. Recimo, ako je u pitanju neki chat, klijent, odnosno korisnik klijent programa svakako ne očekuje da ga server izloguje kada ode da se javi na telefon ili do toaleta. Sa druge strane, ako je u pitanju neka multiplayer igra (pogotovo ako je potezna), onda je to sasvim ok opcija, jer ako neko odugovlači, drugi igrači ispaštaju i izlaze iz igre, pa te "spavače" svakako treba odstraniti čim se ulove. U svakom slučaju, ako još uvek nisi rešio problem, napiši malo više detalja o aplikaciji i čemu služi, pa možda i nađemo najbolje rešenje.
[ Blue82 @ 31.07.2011. 11:16 ] @
E sad ima tu jos nekih caka vezanih za Winsock i TCP. Ako je neko pravio ozbiljniju aplikaciju sa puno konekcija, sigurno zna da citav paket koji saljemo ne mora biti u istom trenutku poslat i ne mora biti poslat u celini vec moze iz delova.
Primera radi ako saljemo podatak "Poruka1|podatak1|podatak2|podatak3|Kraj poruke" moze da se desi da ce zbog popunjenosti buffera poruka biti poslata iz 2 dela "Poruka1|podatak1|podatak2" i posle nekog vremena (1-2s) "|podatak3|Kraj poruke". Kako na prijemu obicno ocekujemo poruku odredjenog formata obe ova poruka nece biti prepoznata ni obradjena.
To sam uspeo resiti tako sto sve nekompletirane poruke, koje se ne zavrsavaju sa "|Kraj poruke" pamtim i dodajem ih na sledecu poruku pa ako opet nije kompletirana cekam sledeci prijem i tako do kraja. Ovo je dobro za klijente jer oni dobijaju od servera poruke redosledom koji im se salje, ali za server to ne vazi jer vise klijenata mu salje poruke pa ako je neka poruka nekompletana prostim spajanjem delova poruka razlicitih ucesnika dobicemo brljotinu.
Znaci ovo ne moze:

Code:

Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim poruka As String
Winsock1(Index).GetData poruka
if poruka= ... Then ...

end if


Nigde nikada nisam uspeo pronaci primer koji to elegantno resava. Imao sam vise pokusaja ali oni samo ublazavaju taj problem, tj. pomazu da do gubljenja podatka redje dodje ali nikada nisam uspeo u tome 100% a da je kod normalan i da ne obradjuje podatke po pola sata (nepotrebno zakomplikovan kod).

Ima li neko resenje za ovo?

[ Shadowed @ 31.07.2011. 11:49 ] @
Pa, to ne bi trebalo da bude neki problem. Napravis niz na koji nadovezujes bajtove kada ih dobijes i svaki put proveris da li je stigao kraj poruke. Ako jeste, od pocetka do tog obelezja kraja poruke je poruka. Onda to odseces (za slucaj da je pocela da dolazi i nova poruka), ono sto ostane je pocetak nove poruke. Bilo bi dobro da proveris da li i taj ostatak ima kraj, i tako dalje sve dok ne izvuces sve poruke koje se nalaze u tom nazovimo ga "globalnom" baferu.
[ Blue82 @ 31.07.2011. 11:57 ] @
U kom smislu niz?
Evo primer. Ovo su poruke koje treba poslati
CLient1|Poruka1|podatak1|podatak2|Kraj poruke" (salje klijent 1)
CLient1|Poruka2|podatak1|podatak2|Kraj poruke" (salje klijent 1)
CLient2|Poruka1|podatak1|podatak2|Kraj poruke" (salje klijent 2)
CLient3|Poruka1|podatak1|podatak2|Kraj poruke" (salje klijent 3)

Na prijemu mozes da dobijes

CLient1|Poruka1|podatak1|podatak2|Kraj poruke"CLient1|Poruka2|podatak1|podatak2|Kraj poruke" (primer lepljenja poruka u jednu, zato sluzi Kraj poruke kojim se poruke razlazu na pojedinacne split (poruka,"|Kraj poruke")

A mozes da dobijes i
CLient2|Poruka1|podatak1 (poruka nije stigla cela)
CLient3|Poruka1|podatak1|podatak2|Kraj poruke" (umedjuvremenu se ubacuje clijent3)
|podatak2|Kraj poruke" (stize kraj poruke klijenta 2)

i kad se sve to slozi na prijemu imas string

CLient2|Poruka1|podatak1CLient3|Poruka1|podatak1|podatak2|Kraj poruke|podatak2|Kraj poruke
Ovo poslednje niti mogu razloziti niti ista uraditi sa tim.
[ Shadowed @ 31.07.2011. 12:09 ] @
OK, nisam dobro procitao tvoju poruku. Vidim da ti je zapravo problem sto ti se mesaju poruke od razlicitih klijenata.
Nisam pipnuo sesticu godinama pa ne znam kako bi se to tacno uradilo, ali potrebno je da klijenta identifikujes na drugi nacin a ne na osnovu sadrzaja poruke. Pogotovo sto moze da se dogodi i da ti sam header ne stigne kompletan pa ti pokvari i samu identifikaciju.
Kada prihvatas vise konekcija, trebalo bi da imas neki RequestID, mozda preko njega mozes da detektujes koji je klijent u pitanju.
[ Blue82 @ 31.07.2011. 12:31 ] @
Ne identifikuje se pomocu header-a, to je bio samo primer kako da razumes ko koju poruku salje. Oni se identifikuju na osnovu niza winsock-ova. Za svakog klijenta se formira jedan sock.

Code:

Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim poruka As String
Winsock1(Index).GetData poruka


Index odredjuje ko je poslao poruku.
[ Shadowed @ 31.07.2011. 13:32 ] @
Onda za svaki winsock spajas njegove podatke u poseban string/niz bajtova pa delis. Tako neces imati onu izmesanu situaciju.
[ vujkev @ 31.07.2011. 13:34 ] @
Moraš da pamtiš šta ti je poslao svaki klijent posebno. Ne možeš da imaš globalnu primenljivu za sve klijente. Trebalo bi da napraviš nešto ovako
Code:

Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim poruka As String
dim Neobradjeno as string

Winsock1(Index).GetData poruka

Neobradjeno = UzmiNeobradjenePodatkeZaKlijenta(index)  'pozoveš neku proceduru koja će na osnovu index-a da ti vrati neobrađene podatke iz neke kolekcije
neobradjeno = neobradjeno & poruka

if neobradjeno= ... Then ...

end if


ukoliko neobradjeno sadrži "kraj poruke" onda obradiš podatke i na kraju za tog klijenta čuvaš šta god je primio posle "Kraj poruke" kako bi sledeći put kad primiš podatke od njega samo nastavio niz. Ukoliko nema "Kraj poruke" onda sve sačuvaš kao neobrađeno za tog klijenta
[ YuMERA @ 31.07.2011. 21:00 ] @
Malo me sad zbunilo ovo o mogucim greskama prilikom konekcije sa vise klijenata istovremeno.

Zanima me samo da li Blue82 i vujkev pricaju o WinSock kontroli sa UDP ili TCP protokolom....
[ vujkev @ 31.07.2011. 22:17 ] @
ja pričao o TCP/IP

kod UDP-a je još komplikovanije jer je jedan UDP paket je makismalne dužine 1024 bajta (ako se ne varam). Ukoliko pokušaš da pošalješ više od te dužine tvoja poruka će naravno biti podeljena u nekoliko paketa. Problem je što primalac ne mora uvek da dobije prvi, pa redom sve ostale pakete, već može da ih dobije totalno izmešano, a na tebi je da ih složiš kako treba. Dodatna "mana" je što pošiljalac nema pojima da li je neko primio tu poruku ili ne.