PDA

View Full Version : [VB6] Creare programma VNC?


bio n3t
26-06-2009, 20:51
Ciao a tutti, oggi mentre usavo Team Viewer mi è venuta una curiosità su come funzioni questo tipo di software. Programmo in VB6 e qualche mese fa avevo provato a fare qualcosa del genere ma tutto a livello testuale ovvero: utilizzando i socket inviavo il comando che volevo eseguire sulla macchina remota e quest'ultima lo eseguiva (parlo di comandi dati dal prompt). In locale funzionava, ma dato che ho Fastweb non riuscivo a comunicare con gli altri al di fuori della rete. Per ovviare a questo problema ho usato uno stratagemma molto grezzo: il comando che io devo inviare alla macchina remota viene salvato come file di testo sul mio server FTP di Altervista, dopodichè l'altro scaricando questo file txt ne leggeva il contenuto, lo eseguiva e salvava l'output sempre su altervista in modo che io potessi leggere se è andato a buon fine o no.

Ora mi sono chiesto come fa Team Viewer a funzionare anche se io che sono Fastweb mi trovo sotto NAT e quindi non direttamente visibile agli altri?
A livello di programmazione come avviene l'invio delle immagini remote?
Infine per fare muovere il mouse in remoto come lo muovo io basta inviare le mie coordinate al suo computer e con la API fare muovere il suo mouse di conseguenza?

Scusate per il post un pò lunghino spero che qualcuno sappia darmi una risposta e soprattutto spero che nessuno mi dia del lamerozzolo perchè non lo sono ;) grazie in anticipo!

fero86
26-06-2009, 22:16
veramente non sapevo che il server VNC funzionasse anche dietro NAT (qualcuno confrma?), comunque esiste una tecnica che si chiama Hole Punching e che é molto piu attuabile se si lavora con UDP piuttosto che TCP; di norma per i programmi di VoIP é naturale usare questa tecnica, anche perché usano UDP in quanto la performance di rete é cruciale e non é indispensabilissimo che i pacchetti arrivino tutti quanti, quindi si vuole evitare l'overhead dovuto a TCP; Skype ad esempio la usa.

per quanto riguarda l'invio di immagini sulla connessione: é un sistema che disapprovo a causa della pesantezza (VNC infatti é molto lento rispetto ad altri, vedi piu avanti), comunque banalmente segui questo loop:
- prendi uno screenshot
- comprimi al volo
- invia sul socket
- il client decomprime e disegna nella sua finestra

esiste un approccio diverso che risulta molto piu efficiente e consiste nell'inviare al client tutte le informazioni necessarie a ricostruire le finestre: posizione, dimensioni, decorazioni, testo contenuto, controlli nativi, ecc.
RDP ad esempio (il protocollo usato dai Terminal Services) prevede questo approccio, infatti le sessioni di Desktop Remoto di Windows sono molto piu ragionevoli dell'uso di VNC; tuttavia in questo modo c'é lo svantaggio del non poter lavorare da remoto con un sistema diverso (es.: con questo sistema non é possibile controllare Linux da remoto con Windows) perché le informazioni necessarie a ricostruire le finestre sono specifiche del subsystem grafico del sistema operativo.

bio n3t
26-06-2009, 22:36
GRAZIE MILLE!! non avrei potuto desiderare una risposta migliore di questa! :D
ho afferrato praticamente tutto tranne sta cosa dell' "UDP Hole Punching". Cioè a livello pratico creo un socket e come protocollo lo imposto su UDP, poi assegno le rispettive porte e dovrei riuscire a comunicare DIRETTAMENTE con il computer remoto?
Oppure devo seguire il ragionamento che ho trovato su QUESTA (http://www.tecnes.com/tecnologie/UDP+hole+punching.html) breve guida? mi sembra di avere capito quindi che funziona così:


IO --> NAT_FASTWEB --> SERVER PUBBLICO --> COMPUTER_REMOTO

viceversa

COMPUTER_REMOTO --> SERVER PUBBLICO --> NAT_FASTWEB --> IO

Se imposto il protocollo TCP sono sicuro che non funziona, con UDP non serve fare nulla di speciale giusto? grazie mille ancora della tua disponibilità :)

bio n3t
27-06-2009, 11:18
up :stordita:

^TiGeRShArK^
27-06-2009, 12:33
showmypc instaura semplicemente una connessione sulla porta TCP 80 di un loro server, che dunque bypassa completamente il NAT.
Teamviewer se non sbaglio utilizza la stessa tecnica, ma sinceramente non ricordo se usa la porta 80...

bio n3t
27-06-2009, 13:50
showmypc instaura semplicemente una connessione sulla porta TCP 80 di un loro server, che dunque bypassa completamente il NAT.
Teamviewer se non sbaglio utilizza la stessa tecnica, ma sinceramente non ricordo se usa la porta 80...

hum ah ok... ma quindi... una cosa che non capisco è che gli utenti dietro NAT non sono mai direttamente collegati con quelli esterni? cioè per ogni servizio sia esso di chat, di VNC, di scambio file occorre passare per un server con IP pubblico e quindi visibile da tutti? sta cosa proprio non riesco a capirla scusate :D
però come fanno alcuni programmi a comunicare direttamente anche se dietro NAT? grazie!

^TiGeRShArK^
27-06-2009, 14:01
hum ah ok... ma quindi... una cosa che non capisco è che gli utenti dietro NAT non sono mai direttamente collegati con quelli esterni? cioè per ogni servizio sia esso di chat, di VNC, di scambio file occorre passare per un server con IP pubblico e quindi visibile da tutti? sta cosa proprio non riesco a capirla scusate :D
però come fanno alcuni programmi a comunicare direttamente anche se dietro NAT? grazie!

il nat non fa altro che tradurre da un indirizzo privato ad uno pubblico mappandolo su una specifica porta dell'indirizzo pubblico.
Per uscire, tu puoi uscire senza problemi dato che provvederà il nat a fare tutto, se invece qualucno dall'esterno vuole contattarti direttamente non può farlo.
Devi essere prima tu a contattare lui, così il nat crea il "canale" e lui ti può rispondere utilizzando lo stesso "canale".
Appoggiandosi a server esterni dunque non si ha alcun problema dato che è il server che viene contattato dal tuo pc e gestisce le connessioni con gli altri utenti allo stesso modo, anche se pure loro sono dietro NAT :p

bio n3t
27-06-2009, 14:13
il nat non fa altro che tradurre da un indirizzo privato ad uno pubblico mappandolo su una specifica porta dell'indirizzo pubblico.
Per uscire, tu puoi uscire senza problemi dato che provvederà il nat a fare tutto, se invece qualucno dall'esterno vuole contattarti direttamente non può farlo.
Devi essere prima tu a contattare lui, così il nat crea il "canale" e lui ti può rispondere utilizzando lo stesso "canale".
Appoggiandosi a server esterni dunque non si ha alcun problema dato che è il server che viene contattato dal tuo pc e gestisce le connessioni con gli altri utenti allo stesso modo, anche se pure loro sono dietro NAT :p

ahhhhhhhhhhhhhhhhhhhh ho capito ora! :D
ok quindi la parte teorica l'ho capita... però dal lato pratico come faccio a far sì che questo "canale" sia sempre lo stesso? ti posso spiegare brevemente in VB6 come lo farei? grazie della disponibilità mi siete di grande aiuto!

^TiGeRShArK^
27-06-2009, 14:23
semplicemente non puoi perchè di solito viene utilizzato un NAT dinamico che, a differenza di quello statico, sceglie sempre una porta diversa per l'instaurazione del canale di comunicazione.
Se il NAT fosse stato statico allora sarebbe stato sufficiente per contattarti dall'esterno utilizzare l'indirizzo pubblico del NAT collegandoti alla porta che poi sarebbe stata girata al tuo pc.
L'unica cosa che puoi fare è utilizzare qualche server esterno a cui appoggiarti che si occupi di gestire le connessioni nattate.

bio n3t
27-06-2009, 14:41
semplicemente non puoi perchè di solito viene utilizzato un NAT dinamico che, a differenza di quello statico, sceglie sempre una porta diversa per l'instaurazione del canale di comunicazione.
Se il NAT fosse stato statico allora sarebbe stato sufficiente per contattarti dall'esterno utilizzare l'indirizzo pubblico del NAT collegandoti alla porta che poi sarebbe stata girata al tuo pc.
L'unica cosa che puoi fare è utilizzare qualche server esterno a cui appoggiarti che si occupi di gestire le connessioni nattate.

mmm... mi diresti un server che conosci che fa queste cose? grazie

^TiGeRShArK^
27-06-2009, 15:04
....non ne conosco...:fagiano:
intendevo che dovresti creartelo tu. :p

bio n3t
27-06-2009, 15:05
....non ne conosco...:fagiano:
intendevo che dovresti creartelo tu. :p

bhe dimmi cosa cercare almeno :D

^TiGeRShArK^
27-06-2009, 15:12
basta crearti un serversocket in ascolto che apra un nuovo thread per ogni nuova connessione in ingresso e devi prevedere un sistema di identificativi univoci che permettono di associare al server i vari pc registrati con le varie connessioni.
Un pò come la password di team viewer, ma se vuoi puoi anche legarla staticamente ad un pc anzichè inserirla ogni volta in maniera dinamica...
A quel punto basta fare da bridge tra la connessione di utente e quella del'altro....

bio n3t
28-06-2009, 13:09
ok grazie! ho cercato un pò come fare ma serve per forza sapere java e io non lo conosco affatto :D
non c'è un servizio in cui mi registro e poi fa tutto lui? :D ho cercato giuro ma non ne ho trovati :cry:

^TiGeRShArK^
28-06-2009, 13:48
ok grazie! ho cercato un pò come fare ma serve per forza sapere java e io non lo conosco affatto :D
non c'è un servizio in cui mi registro e poi fa tutto lui? :D ho cercato giuro ma non ne ho trovati :cry:

che io sappia no...
cmq guarda che i socket e i thread li puoi utilizzare anche con VB6 se non sbaglio... :stordita:

bio n3t
28-06-2009, 14:07
che io sappia no...
cmq guarda che i socket e i thread li puoi utilizzare anche con VB6 se non sbaglio... :stordita:

si i socket lo so, i thread mmmm non saprei :D
comunque con VB6 non posso mettere un programma sul server che dovrà fare da tramite... o sbaglio? :confused:

MarcoGG
28-06-2009, 15:49
si i socket lo so, i thread mmmm non saprei :D
comunque con VB6 non posso mettere un programma sul server che dovrà fare da tramite... o sbaglio? :confused:

Con VB6 vai tranquillo sui Socket.
Servizi, nel senso stretto del termine, non ne puoi creare.
Per quanto riguarda il threading c'è una via, che io sappia, abbastanza "laterale" e comunque non tanto raccomandabile ( può causare instabilità ).

Dal momento che stai praticamente a 1 e mezzo su 3, passa a VB.NET. ;)

bio n3t
28-06-2009, 18:11
Con VB6 vai tranquillo sui Socket.
Servizi, nel senso stretto del termine, non ne puoi creare.
Per quanto riguarda il threading c'è una via, che io sappia, abbastanza "laterale" e comunque non tanto raccomandabile ( può causare instabilità ).

Dal momento che stai praticamente a 1 e mezzo su 3, passa a VB.NET. ;)

si un pò lo so usare VB.NET, però non mi va di imparare qualcosa che per il momento non tutti sarebbero pronti per usare (parlo del net framework necessario altrimenti i programmi non partono), tanto per i programmini come quelli che faccio io non ho grosse esigenze ;)
quindi quale sarebbe questa via "laterale"? :D

MarcoGG
28-06-2009, 19:14
si un pò lo so usare VB.NET, però non mi va di imparare qualcosa che per il momento non tutti sarebbero pronti per usare (parlo del net framework necessario altrimenti i programmi non partono), tanto per i programmini come quelli che faccio io non ho grosse esigenze ;)
quindi quale sarebbe questa via "laterale"? :D

Beh, su questo si potrebbe discutere. In teoria ci sono macchine e macchine su cui anche un applicativo VB6, senza le dovute dll ( Mdac, VB6 Runtime, librerie di sistema, ecc... ) potrebbe trovare serie difficoltà.
Il framework è uno scoglio davvero risibile se paragonato alla difficoltà nell'implementare una soluzione VB6 davvero stabile e sicura che fa uso di threading, e che oltretutto debba "assomigliare" il più possibile ad un Windows Service ( e te lo dice uno che vede con molta simpatia il VB6 / VBA ).
Detto questo, uno dei migliori articoli sul threading in VB6 è probabilmente questo :

http://www.freevbcode.com/ShowCode.Asp?ID=1287

Personalmente non ho mai usato threading in VB6, perciò non ho miei esempi da proporre. Buona lettura... e buona fortuna ! :D

bio n3t
28-06-2009, 23:46
Beh, su questo si potrebbe discutere. In teoria ci sono macchine e macchine su cui anche un applicativo VB6, senza le dovute dll ( Mdac, VB6 Runtime, librerie di sistema, ecc... ) potrebbe trovare serie difficoltà.
Il framework è uno scoglio davvero risibile se paragonato alla difficoltà nell'implementare una soluzione VB6 davvero stabile e sicura che fa uso di threading, e che oltretutto debba "assomigliare" il più possibile ad un Windows Service ( e te lo dice uno che vede con molta simpatia il VB6 / VBA ).
Detto questo, uno dei migliori articoli sul threading in VB6 è probabilmente questo :

http://www.freevbcode.com/ShowCode.Asp?ID=1287

Personalmente non ho mai usato threading in VB6, perciò non ho miei esempi da proporre. Buona lettura... e buona fortuna ! :D

scusami sono ignorante... il threading sarebbe? ma comunque c'entra col mio problema? :stordita:

^TiGeRShArK^
29-06-2009, 00:33
scusami sono ignorante... il threading sarebbe? ma comunque c'entra col mio problema? :stordita:

...un thread, detto in maniera spicciola ma non so quanto comprensibie (:stordita: ) sarebbe l'insieme di istruzioni + piccolo che può elaborare sequenzialmente un processore in parallelo con altre..
praticamente a livello di sistema operativo l'unità + piccola considerata è solitamente il processo, all'interno dei vari processi possono esserci i vari thread che vengono elaborati in maniera concorrente dallo scheduler del sistema operativo...
praticamente se tu hai un Core i7 (Nehalem) con 4 core e l'hyper-treading abilitato puoi elaborare fino ad 8 thread contemporaneamente.
Se riesci quindi a dividere il tuo software in una serie di istruzioni che hanno il livello di esecuzione ottimale quando sono eseguite contemporaneamente in batch di dimensione 8 allora sfrutti completamente la tua CPU.
Nel tuo caso, anche con un processore singolo, il threading serve perchè mentre tu gestisci una richiesta di esecuzione per elaborare una connessione socket che ti è arrivata su una determinata porta su cui sei in ascolto, devi continuare ad ascoltare per altre eventuali connessioni che ti arrivano nel frattempo.
Se non usi il threading appena ti arriva la prima connessione tu la gestisci, ma non puoi fare altro (a meno di sporchissimi escamotàge che *simulano* il threading).
Dunque per gestire un numero imprecisato di connessioni concorrenti la soluzione migliore è aprire un thread per ogni connessione e farla gestire in maniera concorrente al sistema operativo..
...cmq fino a stasera ignoravo il fatto che VB6, come alcune implementazioni di python e ruby (le + diffuse tra l'altro... :mbe: ), non supportasse nativamente il threading... :fagiano:
A questo punto direi di seguire l'ottimo suggerimento di marco di imparare un linguaggio + moderno, come VB.NET, che potrà sempre tornarti utile in futuro, soprattutto tenendo conto del fatto che Microsoft sta studiando una specie di convergenza tra C# e VB.Net, sancendo de facto una promozione a first class language del secondo, che non mi pare affatto una cosa banale... :p

MarcoGG
29-06-2009, 08:41
A questo punto direi di seguire l'ottimo suggerimento di marco di imparare un linguaggio + moderno, come VB.NET, che potrà sempre tornarti utile in futuro, soprattutto tenendo conto del fatto che Microsoft sta studiando una specie di convergenza tra C# e VB.Net, sancendo de facto una promozione a first class language del secondo, che non mi pare affatto una cosa banale... :p

Vero. :)
Ho letto anch'io da varie fonti su questo progetto di convergenza.
MS ha già pensato da un anno a questa parte, di fondere i team VB e C# in un unico "Visual Studio Managed Languages Team". Perciò tutto lascia pensare che a partire da VB10 e C#4, la direzione presa sarà senza dubbio questa, alla faccia di chi credeva, o forse sperava ( come i soliti "sacerdoti" di C & dintorni ) che nel futuro solo C# avrebbe beneficiato dei miglioramenti da "linguaggio serio", mentre VB avrebbe avuto uno sviluppo più orientato a procedure di tipo RAD...
Comunque sia io la convergenza la vedo già a partire da VS 2005, e sicuramente C# e VB si assomigliano molto di più in VS 2008, che non in VS.NET ( 2002 ), e devo dire che apprezzo molto questa decisione di MS, a patto però che non decidano di mettermi le graffe e i punto-e-virgola anche in VB ! :D :D :D