PDA

Prikaži potpunu verziju : Kreiranje remote control aplikacije


doctor
21.12.2010, 22:27
Eh, ovako, volim da učim kroz rad, i došao sam na ideju da razvijem aplikaciju koja radi isto što i TeamViewer, na primer.

Radio bih je (client side deo) u VB.Net ili C#, s tim što C# u principu ni ne poznajem, a VB poznajem prilično solidno, pa bih se pre opredelio za njega, da ga usavršim koliko god mogu kad već toliko dugo radim sa njim.

Prvo, znam da je ovo veliki posao ali sam spreman da uložim vremena i truda koliko god je potrebno jer želim da uđem u taj "svet" server/client aplikacija koje funkcionišu preko neta pomoću standalone servera ili direktno (ovo prvo me trenutno najviše zanima).

Dakle, moja pitanja su:
1. Na kom principu bi funkcionisao server na netu, i u kom jeziku bi bilo najbolje napisati server side deo aplikacije (ASP.Net, PHP...?)
2. Na koji se način odvija client-server komunikacija i kako implementirati pravu enkripciju (i neki link o enkripciji i dekripciji podataka uopšte)?
3. Neki koristan link o tome kako se u .Net-u prave ovakve aplikacije i neki koristan link o System.Net klasi, pošto se ako sam dobro skontao ona koristi za bilo kakvu vrstu lokalne i "globalne" komunikacije.

=>
U principu, zanima me kako bi tekao razvoj ovakve aplikacije, kako bi funkcionisala, šta bi sve trebalo da znam, i odakle početi.

I, da napomenem ponovo, znam koliki je ovaj zalogaj za mene (i bilo koga ko radi ovo sam) ali sam spreman da radim da bih naučio što je više stvari moguće, tako da bih vas molio da ne bude komentara tipa "mani se ćorava posla."

Hvala svima unapred na pomoći, predlozima i sugestijama.

Ivan-94
22.12.2010, 0:26
Eh, ovako, volim da učim kroz rad, i došao sam na ideju da razvijem aplikaciju koja radi isto što i TeamViewer, na primer.

Radio bih je (client side deo) u VB.Net ili C#, s tim što C# u principu ni ne poznajem, a VB poznajem prilično solidno, pa bih se pre opredelio za njega, da ga usavršim koliko god mogu kad već toliko dugo radim sa njim.

Prvo, znam da je ovo veliki posao ali sam spreman da uložim vremena i truda koliko god je potrebno jer želim da uđem u taj "svet" server/client aplikacija koje funkcionišu preko neta pomoću standalone servera ili direktno (ovo prvo me trenutno najviše zanima).

Dakle, moja pitanja su:
1. Na kom principu bi funkcionisao server na netu, i u kom jeziku bi bilo najbolje napisati server side deo aplikacije (ASP.Net, PHP...?)
2. Na koji se način odvija client-server komunikacija i kako implementirati pravu enkripciju (i neki link o enkripciji i dekripciji podataka uopšte)?
3. Neki koristan link o tome kako se u .Net-u prave ovakve aplikacije i neki koristan link o System.Net klasi, pošto se ako sam dobro skontao ona koristi za bilo kakvu vrstu lokalne i "globalne" komunikacije.

U principu, zanima me kako bi tekao razvoj ovakve aplikacije, kako bi funkcionisala, šta bi sve trebalo da znam, i odakle početi.

I, da napomenem ponovo, znam koliki je ovaj zalogaj za mene (i bilo koga ko radi ovo sam) ali sam spreman da radim da bih naučio što je više stvari moguće, tako da bih vas molio da ne bude komentara tipa "mani se ćorava posla."

Hvala svima unapred na pomoći, predlozima i sugestijama.
1.Ja bas sad radim sa web servisima...i odlucio sam se za php koristeci nusoap (http://sourceforge.net/projects/nusoap/) biblioteku(tutorial (http://www.sanity-free.com/125/php_webservices_and_csharp_dotnet_soap_clients.htm l)), najpre zato sto za asp.net trebas da nadjes hosting...

2.Ako koristis web service onda se komunikacija obavlja preko SOAP protokola, ali ako posebno programiras server koji mora da bude stalno da bude ukljucen, onda se komunikacija vrsi preko TCP/IP.A za enkripciju mozes da napises neki tvoj algoritam ili da koristis neki vec postojeci(MD5,AES,DES,RSA,SHA...) pa da podatke saljes tako enkriptovane pa da ih client koji ih prima dekriptuje.

3.
http://www.codeproject.com/KB/webservices/phpsoapwebservicescsharp.aspx
http://www.sanity-free.com/125/php_webservices_and_csharp_dotnet_soap_clients.htm l
http://www.codeproject.com/KB/IP/TCPIPChat.aspx
http://www.codeproject.com/KB/IP/tcpserverall.aspx

Sve ti je to za C#, a mozes i na codeproject-u da nadjes i za VB.

irreal
22.12.2010, 2:31
1.Ja bas sad radim sa web servisima...i odlucio sam se za php koristeci nusoap (http://sourceforge.net/projects/nusoap/) biblioteku(tutorial (http://www.sanity-free.com/125/php_webservices_and_csharp_dotnet_soap_clients.htm l)), najpre zato sto za asp.net trebas da nadjes hosting...

2.Ako koristis web service onda se komunikacija obavlja preko SOAP protokola, ali ako posebno programiras server koji mora da bude stalno da bude ukljucen, onda se komunikacija vrsi preko TCP/IP.A za enkripciju mozes da napises neki tvoj algoritam ili da koristis neki vec postojeci(MD5,AES,DES,RSA,SHA...) pa da podatke saljes tako enkriptovane pa da ih client koji ih prima dekriptuje.

3.
http://www.codeproject.com/KB/webservices/phpsoapwebservicescsharp.aspx
http://www.sanity-free.com/125/php_webservices_and_csharp_dotnet_soap_clients.htm l
http://www.codeproject.com/KB/IP/TCPIPChat.aspx
http://www.codeproject.com/KB/IP/tcpserverall.aspx

Sve ti je to za C#, a mozes i na codeproject-u da nadjes i za VB.

web servis nije pogodan za trajnu konekciju gde se konstantno salju pokreti misa i tasteri sa tastature i konstantno prima slika sa udaljenog racunara.
Nikako nije pogodan web servis.
samo mu ime kaze, on je servis, uradi nesto i zavrsio je, on je stateless (ne prati sesije) itd.

sto se tice enkripcije, tesko da ce koristiti MD5 ako ocekuje da druga strana to dekriptuje, Hash ne moze da se dekriptuje u originalnu vrednost.

a sto se tice ASP.NET-a, da, treba ti hosting, al isto tako ti i za PHP treba hosting, ne vidim u cemu je razlika ?

Oba imaju windows servere koje mozes sam da pokreces na svom racunaru (s' tim sto asp.net, jer je microsoftov, ima daleko bolju podrsku i integraciju sa windowsom)

doctor
22.12.2010, 12:28
Jasno mi je da je i za ASP.Net potreban server kao i za PHP.

Jasno mi je i to da ASP.Net server mogu da pokrećem na svom računaru, ali moj računar nema statičku IP (mada nije problem da odradim web servis, ili bilo šta slično, koji bi "pratio" moj IP).

Ali nisam te baš najsjajnije razumeo kako je onda najbolje da realizujem ovo pošto kažeš da ne koristim web servise jer su stateless?

irreal
22.12.2010, 12:49
Jasno mi je da je i za ASP.Net potreban server kao i za PHP.

Jasno mi je i to da ASP.Net server mogu da pokrećem na svom računaru, ali moj računar nema statičku IP (mada nije problem da odradim web servis, ili bilo šta slično, koji bi "pratio" moj IP).

Ali nisam te baš najsjajnije razumeo kako je onda najbolje da realizujem ovo pošto kažeš da ne koristim web servise jer su stateless?


Sve sto vazi za ASP.NET vazi i za PHP, sto se tice uslova hostovanja, sve je identicno!

znaci ako trazis hosting, skoro svi hostinzi nude i asp.net hostovanje i php hostovanje.

ako ces lokalno da hostujes sam, apsolutno ti je svejedno da li ces instairati php server ili asp.net server, za oba moras da konfigurises portove, pratis promenu ip adrese itd.

Dakle, samo sam hteo da kazem da se asp.net nista ne razlikuje od php-a po zahtevnosti jer je ivan-94 napisao tako da ispade da php radi sam od sebe magicno a za asp.net treba hosting.

Sto se tice ip adrese, neces pisati nikakav web servis za pracenje ip adrese.

Web servis ne sluzi ni za to. Za ip adresu bi koristio jednostavno neki besplatan program (ili napisao svoj) koji radi na tvom lokalnom racunaru i nakon svake promene tvoje ip adrese osvezava neki DNS unos na internetu.
DNS unos mozes da kupis (www.stagodoces.nesto) ili da iskoristis besplatan (stagodhoces.dyndns.org ili slicni root domeni) itd.

sto se tice samog tvog pitanja ne vidim bolji nacin nego da se konektujes direktno preko tcp/ip-a. obe strane se kace na tvoj server kao klijenti i tvoj server razmenjuje podatke izmedju njih.
Nisam nikada radio slicne aplikacije tako da mozda i ima bolji nacin al ja ga ne znam.

Procitaj kako radi neki od protokola koji vec postoje. VNC protokol je jako fin i nacices mnogo informacija o njemu. VNC protokol podrzava i sliku i upravljacki interfejs. sad samo ostaje da ga implementiras da radi preko tvog centralnog servera :)

doctor
22.12.2010, 13:35
Da, pao mi je na pamet DNS. :)

Dakle, server (realno ne mora da bude ni ASP ni PHP, s obzirom na to da ću da koristim direktne konekcije već to može da bude jedan "programčić" koji će da obavlja ceo posao), DNS, program koji "prati" moj IP i osvežava DNS, i direktna veza putem TCP/IP (uz VNC, ali ne znam šta je VNC, informisaću se o tome, naravno).

Hvala puno na pomoći, sad će zimski raspust pa ću imati vremena na pretek da se bavim ovim. Jedva čekam :D

Ivan-94
22.12.2010, 14:13
@irreal
Mislio sam kad sam spomenuo hosting, da ga je malo teze pronaci.To govorim iz licnog iskustva, naravno mozda nisam trazio na pravom mestu.

irreal
22.12.2010, 19:18
@irreal
Mislio sam kad sam spomenuo hosting, da ga je malo teze pronaci.To govorim iz licnog iskustva, naravno mozda nisam trazio na pravom mestu.

hmm... ja kada sam uzimao hosting, pozvao Sezampro hosting i pitali me da li hocu windows i asp.net ili linux i php.

nije bilo narocito tesko.

a moze i da se ukuca asp.net hosting na google i problem resen.


Nego, da se razumemo, ja se samo zalazem za sto bolje objektivno informisanje.

Licno ne preferiram asp.net preko php-a niti se zalazem za koriscenje istog.

doctor
30.12.2010, 1:36
Razradio sam koncept cele aplikacije, sad je ostalo još da se napiše ista :)
Kako sam VB6 "programer" jer me je do sada služio za sve što mi je trebao, socketi u .Net i principi njihovog rada su mi nejasni, a tutoriali koje nalazim me samo zbunjuju.

Pa, ako može neko da baci neki tut o osnovama socketa koji bi i duduku bio razuman, bio bih mu zahvalan na tome :)

(Da napomenem da sam Guglao, ali kao što rekoh, nije mi sve baš najjasnije, s obzirom na to da mi je um i dalje u čistom event-driven programiranju, pa sam sad ovde sve pobrkao).

MG-RAY
30.12.2010, 1:47
Razradio sam koncept cele aplikacije, sad je ostalo još da se napiše ista :)
Kako sam VB6 "programer" jer me je do sada služio za sve što mi je trebao, socketi u .Net i principi njihovog rada su mi nejasni, a tutoriali koje nalazim me samo zbunjuju.

Pa, ako može neko da baci neki tut o osnovama socketa koji bi i duduku bio razuman, bio bih mu zahvalan na tome :)

(Da napomenem da sam Guglao, ali kao što rekoh, nije mi sve baš najjasnije, s obzirom na to da mi je um i dalje u čistom event-driven programiranju, pa sam sad ovde sve pobrkao).

Pogledaj Programming Challenges, to je bio jedan od zadataka dako da imas par resenja tamo, cini mi se...

doctor
30.12.2010, 11:41
Našao sam challenge, i nisam našao sourceve, već samo rasprave o konkretnim problemima uglavnom o Winsocketu (koji poznajem ali ne želim da radim sa njim).

Ako neko nađe nešto neka baci ja odoh da Guglam... Again :)

NISAM NESTO SMART
30.12.2010, 13:34
Evo pogledaj ovde ima uopšteno o socketiima: LINK (http://beej.us/guide/bgnet/output/html/multipage/index.html)

EclipsE
30.12.2010, 17:24
Našao sam challenge, i nisam našao sourceve, već samo rasprave o konkretnim problemima uglavnom o Winsocketu (koji poznajem ali ne želim da radim sa njim).

Jbg, davno su radjeni challengei pa nemam source onog mog sto sam radio u VB.NET :/

Mozes da skines gotove programe:
http://www.sk.rs/forum/showpost.php?p=297949&postcount=701
http://www.sk.rs/forum/showpost.php?p=298611&postcount=704

pa da reflectujes i vidis source, nije bas najbolje ali mozes da pokupis par ideja ^^ (PS bolje gledaj samo MG-RAYov program, a ne i moj xD)

doctor
30.12.2010, 18:05
Reflectujem...? :o

irreal
30.12.2010, 18:14
U principu manje vise svi se pogube kad prvi put krenu da rade sa socketima.
Preporucujem ti da koristis tcplistener i tcpclient klase (unutar System.net.sockets namespace-a)

sa te dve klase mozes da odradis kompletnu server klijent aplikaciju.
listener ima jednostavnu metodu kojom zadas port na kojem slusas, krenes slusanje i onda imas dve opcije. ili pozoves metodu koja ce da blokira thread dokle god ne primi konekciju ili proveravas po svom nahodjenju da li ima dolaznih konekcija koje cekaju da se prihvate i onda ih prihvatis.

u principu ces raditi tako sto otvoris novi thread, zadas mu da primi konekciju cim se pojavi pokusaj i taj thread ce da bude zablokiran dok ceka. naravno, to nece biti glavni thread aplikacije, pa nece cela aplikacija da se zabode dok cekas konekciju.

to je manje vise to. tcpclient je jednostavan, das mu gde da se konektuje i kazes connect.

kada si ostvario konekciju komunikacija se svodi na stream-ove odnosno pisanje i citanje iz stream-a.

trazi primere za tcpclient i tcplistener pa ce ti pokazati kako da proveris da li je nesto stiglo, procitas, odgovoris, itd.

server i klijent mogu da se dogovore da naizmenicno razmenjuju podatke (slusas pa pises pa slusas) ili mozes da otvoris dve konekcije, jedna koja slusa druga koja pise, da bi oba mogla nezavisno u bilo kojem trenutku nesto da proslede. zavisi od tvojih potreba.

To bi bilo to, onako, krajnje ukratko.

Geomaster
30.12.2010, 22:40
Reflectujem...? :o
Dekompajliraš :)
http://www.red-gate.com/products/dotnet-development/reflector/

@EclipsE:
Nostalgija :qliranje:

doctor
30.12.2010, 23:05
Pretpostavio sam da je to u pitanju nego me je Gugl razuverio :) Baš ću da pogledam to.

MG-RAY
31.12.2010, 0:34
Jbg, davno su radjeni challengei pa nemam source onog mog sto sam radio u VB.NET :/

Mozes da skines gotove programe:
http://www.sk.rs/forum/showpost.php?p=297949&postcount=701
http://www.sk.rs/forum/showpost.php?p=298611&postcount=704

pa da reflectujes i vidis source, nije bas najbolje ali mozes da pokupis par ideja ^^ (PS bolje gledaj samo MG-RAYov program, a ne i moj xD)

Nemoj ni moj, krs je... Davno je to bilo i stidim se... :D

Potrazicu sutra source pa ti saljem ako nadjem...

EclipsE
31.12.2010, 16:29
E da, mozda moze ovo da ti pomogne: http://code.google.com/p/lidgren-network-gen3/

Todors
31.12.2010, 18:39
Evo ja sam pronašao, neki vrlo lep i veoma jednostavan, server-klijent chat tutorijal preko googla.

http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html

doctor
13.1.2011, 17:11
Okej, nakon 3 dana čitanja, socketi su mi jasni onoliko taman koliko su mi potrebni, poznajem ih dovoljno.
Eh, sada, počeo sam sa izradom aplikacije, pa sam došao do određene tačke, gde sam hteo da testiram kako to radi na dve različite mašine (koristim .Net 2.0), i mašina na koju sam prekopirao program nikako neće da se poveže na host mašinu na kojoj drugi program "sluša." Ubacio sam programe u firewall liste (da ih ne blokiraju) ali i dalje ne uspevaju da se povežu. Da napomenem da prilikom rada na jednoj mašini, kada koristim 127.0.0.1 (localhost) sve radi sasvim normalno - imam sliku, chat radi... Ali preko mreže ne mogu čak ni da se konektujem normalno već "popijem" timeout grešku kod klijenta.

Geomaster
13.1.2011, 20:00
Da li je server mašina iza rutera? Ako jeste, jel su forwardovani svi portovi i jel su firewallovi na ruteru isključeni? Na kojoj IP adresi sluša server, da ne sluša možda greškom na loopback IP-ju ili na WAN adresi (ako je iza rutera)?

doctor
13.1.2011, 20:27
Pazi, u mreži smo ja i komša, moja 2 kompa su na mom switchu (običan, nije managable), i sve to je povezano na njegov ruter, ali ne verujem da je do toga, pre jedno godinu dana sam sa istom ovom konfiguracijom mreža pravio nešto slično u VB6 sa Winsocketom i "prolazilo" je bez problema. Tačnije sve aplikacije "prolaze" bez problema, osim ove.
Pratio sam, i klijent šalje podatke, ali server ne prima nikakve (mreža 100% radi).

'Ajde baš ću da probam i sa virtuelnim mašinama, sad mi tek to pade na pamet... I sa laptopom kad instaliram 2.0 redistributablese na njega pošto je sveže reinstaliran OS...

Geomaster
13.1.2011, 20:51
Aha, nisam znao da ste u LAN-u. Jel si proverio IP adrese i portove? Često pomaže da staviš statičke adrese na oba kompa. Uzmi neki network traffic monitor pa pogledaj da li se podaci stvarno šalju sa klijenta, i da li se stvarno ne primaju na serveru.

doctor
14.1.2011, 3:26
Statičke su... Klijent šalje podatke (zahtev da uspostavi konekciju) ali server nikako ne prima. Nisam bio kod kuće ceo dan, tek sutra ako stignem pokušaću ponovo, pa javim šta sam uradio.

irreal
14.1.2011, 3:41
Statičke su... Klijent šalje podatke (zahtev da uspostavi konekciju) ali server nikako ne prima. Nisam bio kod kuće ceo dan, tek sutra ako stignem pokušaću ponovo, pa javim šta sam uradio.

najverovatnije je kao sto je vec spomenuto da server slusa na pogresnom ip endpoint-u.

To nam nisi potvrdio da si siguran da je pravilno podeseno.

doctor
14.1.2011, 18:19
Ček, ja nisam koristio IP Endpoint... Tačnije ne znam ni šta je to? To mu dođe IP servera, tj. da serveru kažem da prihvata samo pakete namenjene Endpointu koji mu dam?

Odredio sam samo port na kome da sluša, primer:
tcpListener as New TcpListener = TcpListener(5555)
tcpListener.Start()

Jeste da mi ispod piše da je metoda obsolete, ali nisam mislio da mi je potreban i Endpoint. Može neko objašnjenje o tome, primer...? Sve što sam nalazio na netu se radilo samo sa slušanjem na portu.

EDIT: Stavio sam IPAddress.Any za Endpoint i sada sve radi :)
1. Inače, i dalje me zanima šta zapravo predstavlja Endpoint parametar koji prosleđujem prilikom kreiranja TcpListener objekta?

2. I, da, kada "hvatam" screenshot primetio sam da zauzeće procesora dosta skače. Koristim funkciju za hvatanje screenshota koja izgleda ovako:
Dim screenImage As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(screenImage)
graphic.CopyFromScreen(New Point(0, 0), New Point(0, 0), New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height))
Return screenImage
Bitmap se kasnije "konvertuje" u PNG (JPG je isuviše loš), čuva u MemoryStream i onda šalje.
Kasnije ću praviti "diferenciranu" sliku, tj. slaću samo piksele koji se na novom screenshotu razlikuju od onih na prethodnom.

a) Postoji li neki način koji je manje "gladan" što se tiče procesora? Moram li da pozivam API da bi ovo brže radilo? Jer ako budem želeo da "hvatam", recimo, 10 slika u sekundi, ovo će jesti mnogo procesorskog vremena.
Na starom Celeronu na 850MHz, cpu ode na 100% i proces "hvatanja" i slanja screenshota traje sigurno sekundu možda i malo više.
b) Postoji li u frameworku funkcija koja bi smanjila broj boja na bitmapi tako da uštedim na veličini slike?

irreal
15.1.2011, 3:34
Ček, ja nisam koristio IP Endpoint... Tačnije ne znam ni šta je to? To mu dođe IP servera, tj. da serveru kažem da prihvata samo pakete namenjene Endpointu koji mu dam?

Odredio sam samo port na kome da sluša, primer:
tcpListener as New TcpListener = TcpListener(5555)
tcpListener.Start()

Jeste da mi ispod piše da je metoda obsolete, ali nisam mislio da mi je potreban i Endpoint. Može neko objašnjenje o tome, primer...? Sve što sam nalazio na netu se radilo samo sa slušanjem na portu.

EDIT: Stavio sam IPAddress.Any za Endpoint i sada sve radi :)
1. Inače, i dalje me zanima šta zapravo predstavlja Endpoint parametar koji prosleđujem prilikom kreiranja TcpListener objekta?

IPEndpoint je adresa na kojoj planiras da primas podatke.

Koja je ip adresa tvog racunara ?
Možda ćeš se zaleteti i odgovoriti na to pitanje onako kako bi i većina odgovorila, kako se podrazumeva obično, da je u pitanju, npr 192.168.0.2
ali to nije ispravno.

to je ip adresa jedne tvoje mrezne kartice (koja je najcesce jedina fizicka, a tu je uvek i specijalna 127.0.0.1, loopback adresa, koja je tebi ustvari i pravila problem)

sta ces ako na racunaru imas 3 mrezne kartice i sve tri su nakacene na tri razlicite mreze?

Tcplisteneru mozes da kazes da zelis samo sa jedne od tih 3 mreza da primas klijente a mozes da kazes i Any, kao sto si ti i stavio.


Sto se tice drugog dela tvog posta, bez dubokog zalazenja u native kod, tesko da ces dovoljno brzo hvatati slike i kompresovati ih za slanje.

metoda diferencijala ce svakako pomoci dosta sa slanjem, ne toliko sa samim uzimanjem.

Previse sam umoran da bi potrazio potpunije savete i tehnike a to nije tema kojom sam se puno bavio (graficki rad iz .net-a) tako da cu ostati na tome za sada :)

Geomaster
15.1.2011, 16:45
2. I, da, kada "hvatam" screenshot primetio sam da zauzeće procesora dosta skače. Koristim funkciju za hvatanje screenshota koja izgleda ovako:
Dim screenImage As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(screenImage)
graphic.CopyFromScreen(New Point(0, 0), New Point(0, 0), New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height))
Return screenImageBitmap se kasnije "konvertuje" u PNG (JPG je isuviše loš), čuva u MemoryStream i onda šalje.
Kasnije ću praviti "diferenciranu" sliku, tj. slaću samo piksele koji se na novom screenshotu razlikuju od onih na prethodnom.

a) Postoji li neki način koji je manje "gladan" što se tiče procesora? Moram li da pozivam API da bi ovo brže radilo? Jer ako budem želeo da "hvatam", recimo, 10 slika u sekundi, ovo će jesti mnogo procesorskog vremena.
Na starom Celeronu na 850MHz, cpu ode na 100% i proces "hvatanja" i slanja screenshota traje sigurno sekundu možda i malo više.
b) Postoji li u frameworku funkcija koja bi smanjila broj boja na bitmapi tako da uštedim na veličini slike?
a) Ne verujem da ćeš moći iz .NET-a. Ako hoćeš neko veće ubrzanje kod samog hvatanja screenshota, kao što reče irreal moraćeš da uđeš u native kôd. Ako ćeš da radiš na multi-core procesoru, eventualno može da pomogne paralelizacija, ali opet ne vidim kako da to hvatanje i kompresovanje screenshota da razbiješ u dva (ili više) nezavisna thread-a. Nikad nisam radio sa tim, ali možda bi pomoglo (moguće da sam sad žešće lupio) da uzmeš hDC ekrana i preko gdi32.dll (ili nekog drugog, nisam siguran koji se koristi) vratiti sadržaj hDC-a. Opet, samo neka uopštena pretpostavka, nikad se nisam bavio ovim. A cenim da i funkcija u .Net-u radi isto. U svakom slučaju, kopiranje toliko memorije odjednom, na kratke vremenske intervale, sigurno mora da jede mnogo CPU cycle-ova.

b) Ovde imam malo konkretniji odgovor. Ja bih uposlio GPU da generiše diferenciranu sliku od dve ("before" i "after"), i taman možeš da staviš neki manji format za sliku (tipa A1R5G5B5 odnosno 16 bita - 1 za alpha (ima razlike u pikselu - nema razlike u pikselu) i po pet za svaku boju (RGB)). To bi znatno smanjilo rezultujuću sliku. Za framework ne znam, to bi mogao da kaže neko ko je radio u .NET-u, ali je ovo jako brz način, pošto je pixel shader za generisanje te slike jako jednostavan i i na nekoj integruši bi sigurno brzo radio, na oko 100fps, možda i više, a pritom ne upošljavaš CPU dodatno, osim da podesi semplere za shader i "pokupi" generisanu sliku kao render target.
Ako hoćeš da ubrzaš uzimanje, možeš na sâmom kompu da smanjiš bit depth na 16, mada to nije dobra praksa (da smanjiš bit depth na celom ekranu da bi brže slao screenove).

doctor
15.1.2011, 18:54
a) Hmh, čitao sam po netu, tip ima isti problem kao ja i pozivao je API funkcije i rekao da "jedu" isto resursa koliko i funkcija u .Net, što verovatno znači da se funkcija svodi na pozivanje API-ja bez nekog nativnijeg koda. Proguglaću još malo sutra.

Inače, u pravi si izgleda za to sa hDC-om: http://www.vbdotnetheaven.com/Uploadfile/mgold/ScreenCaptureUtilityVB11162005063518AM/ScreenCaptureUtilityVB.aspx

b) Ti si se bavio game devom pa ti je jasno kako bi to odradio a ja pojma nemam :D Tek baratam osnovama GDI+, pa ako to može uz pomoć njega... Daj nešto konkretnije, ako imaš, neki link ili slično. Mogao bih da uposlim GPU, to uopšte nije loša ideja, ali bih rekao da je količina znanja koja je potrebna za to daleeeko veća od mog znanja...

Geomaster
15.1.2011, 19:34
b) Ti si se bavio game devom pa ti je jasno kako bi to odradio a ja pojma nemam :D Tek baratam osnovama GDI+, pa ako to može uz pomoć njega... Daj nešto konkretnije, ako imaš, neki link ili slično. Mogao bih da uposlim GPU, to uopšte nije loša ideja, ali bih rekao da je količina znanja koja je potrebna za to daleeeko veća od mog znanja...
GDI+ je softverski sistem koji renderuje sve na CPU-u, tako da nema šanse da iskoristiš GPU. Ako hoćeš da uradiš ovo što ti predlažem, moraćeš da skineš DirectX SDK i otvoriš neki od sample-ova koji se bavi post processingom. Video sam da je Microsoft u novijim releasovima SDK-a dosta poradio na .NET jezicima, tako da ćeš sigurno naći sve što ti je potrebno. Međutim, moraćeš malo da uđeš u programiranje sa DirectX-om, a ja nisam siguran koliko si spreman da se sad bakćeš s tim (iako, ako te privuče, možeš da se preorijentišeš :D). Za tvoje potrebe treba da uradiš sledeće:

1. Initializuješ Direct3D. Nikakva filozofija, čak ti ne treba ni prozor na koji renderuješ.
2. Initializuješ teksturu iz tog screenImage-a. Verujem da je to moguće u .Net-u odraditi bez nekih većih problema, pošto se čuva u memoriji kao bitmapa, samo trebaš da proslediš tu memoriju i podesiš texture format.
3. Napraviš novu teksturu, sa manje boja (ako hoćeš), daš joj prikladne dimenzije, postaviš je za render target.
4. Napraviš quad u ravni.
5. Initializuješ pixel i vertex shader ili .fx fajl (to je još bolje) pa napraviš materijal od njih i dodeliš taj materijal quadu. Najbrže rešenje je da iz vertex shadera za poziciju na ekranu vratiš texcoord da bi dobio quad tačno dimenzija ekrana tj. (0,0) - (1,1). Pixel shader će da obavlja posao - imaće dva semplera, jedan za render target (uzeće njegovu prethodnu sliku kao "before") i novi screenshot ("after"). Treba da uporedi vrednosti iz oba semplera i vrati piksel sa alpha vrednošću 0 ako su isti, a alpha 1 i potrebnu boju ako su različiti.
6. Renderuješ.
7. Pošalješ serveru sadržaj render targeta.

E sad, ovo je žešće težak posao, i možda bi bilo bolje da se ne mlatiš s tim, nego da to uradiš softverski preko GDI+-a. Međutim, na tom Celeronu na 800MHz nema šanse da sve radi za toliko kratko vreme, posebno ne da fetchuje screenshot i da softverski generiše diferenciranu sliku. Ti vidi - uporedi pros & cons pa odluči. Ja sam tu ako ti zatreba pomoć - nikad nisam radio sa managed DX-om, ali mogu teorijski da ti pomognem. I da, mogu da ti pomognem da napišeš vertex i pixel shader ako nećeš da učiš HLSL :D

Belphegor
15.1.2011, 21:35
@Geomaster

Najbrže rešenje je da iz vertex shadera za poziciju na ekranu vratiš texcoord da bi dobio quad tačno dimenzija ekrana tj. (0,0) - (1,1).
U zavisnosti od verzije DirectX-a, za 9-tku recimo treba obratiti paznju na Mapping texels to pixels (http://msdn.microsoft.com/en-us/library/bb219690%28v=vs.85%29.aspx) a dok za 10 - 11 mislim da je to reseno pa ne mora rucno da se "budzi".

doctor
16.1.2011, 0:59
Kuku lele joj šta me snađeeee :D
Ako ne nađem elegantnije rešenje... Moraće nešto da se odradi tako kako si naveo :)

Geomaster
16.1.2011, 1:06
Ako ne nađem elegantnije rešenje...
YOU HAVE INSULTED MY PRINCIPLES—

Nije neelegantno rešenje, mnogo programa za obradu slika ili videa, pa i mnogi drugi koji ti ni na kraj pameti ne bi bila, koriste GPU ovako :)

doctor
16.1.2011, 1:11
Jasno, jasno :D Izvini, čoveče :D

Elem, nisam ja mislio da nije elegantno, ali i tako sam tek "uplovio" kako valja u .Net i sada još da se bakćem i sa DX-om - ima da osedim :D Zato sam i rekao - ako ne nađem neki efikasniji način, onda ide DX :)

Geomaster
16.1.2011, 1:12
Jasno, jasno :D Izvini, čoveče :D

Elem, nisam ja mislio da nije elegantno, ali i tako sam tek "uplovio" kako valja u .Net i sada još da se bakćem i sa DX-om - ima da osedim :D Zato sam i rekao - ako ne nađem neki efikasniji način, onda ide DX :)
Ma opušteno :D Neka, neka, kad se setim da sam ja učio specifikaciju JPG formata sa sve kompresijom, samo da is VB6-ice ne izbacujem .BMP nego .JPG fajlove zbog veličine :D

doctor
3.2.2011, 21:28
Jbla me ova moja aplikacija.
Nikako da nađem način da "hvatam" ekran a da pritom CPU usage ne skoči na 100% u tom trenutku na sekund-dva. Zaista ne mogu da se bakćem sa DX-om, nisam imao do sada iskustava u radu sa njim, a sada da ga učim da bih mogao da hvatam screenshotove, nema smisla, bar ne meni.

Imate li neki konkretan predlog kako da ovo izvedem?

Geomaster
3.2.2011, 21:50
Jbla me ova moja aplikacija.
Nikako da nađem način da "hvatam" ekran a da pritom CPU usage ne skoči na 100% u tom trenutku na sekund-dva. Zaista ne mogu da se bakćem sa DX-om, nisam imao do sada iskustava u radu sa njim, a sada da ga učim da bih mogao da hvatam screenshotove, nema smisla, bar ne meni.

Imate li neki konkretan predlog kako da ovo izvedem?
Ništa direktnije od Windowsog API-ja ne postoji, bar koliko ja znam (ne računajući asembler i stvari o kojima ne verujem da razmišljaš sad :D). Da bi rasteretio CPU moraćeš da uposliš GPU, bar da pravi difference image i downsampluje screenshot. Mada ćeš opet morati da koristiš CPU da dobiješ tu sliku, što će opet podići usage, tako da korišćenje GPU-a možda neće mnogo ni pomoći.

Ne znam šta da ti predložim - eventualno da sampluješ manje piksela iz originalnog hDC-a za desktop. Dakle, recimo, da uzmeš svaki drugi red piksela umesto svakog. To će malo smanjiti memory bandwidth, ali računaj da za rezoluciju 1024x768 trebaš da uzmeš 786432 piksela, puta 32 bita (4 bajta) X8R8G8B8 jednako ukupno 3145728 bajta odnosno 3 MB podataka svaki put kad uzmeš screenshot. Ako bi uzimao svaku drugu liniju piksela opet bi ti trebalo 1,5 MB po jednom fetchovanju ekrana. Ako hoćeš da dosta spustiš CPU usage možeš da uzimaš, recimo, svaki četvrti piksel, ali time mnogo gubiš na kvalitetu.

doctor
3.2.2011, 22:18
Hmh, hvala, ali baš sad gledam, na primer, Team Viewer, kako on može da radi tako dobro a da jede tako malo resursa? Nije mi jasno.:confused:
Ispada da on nekako direktno "krade" video buffer... Moraću da se pozabavim DX-om :(