You are on page 1of 8

Aplicaciones Cliente/Servidor en Gambas

Prof: Mileti, P.

Al igual que un usuario se comunica con el programa por medio del teclado, dos programas se pueden comunicar entre s por medio Sockets. Se podra decir que los sockets son canales por los cuales dos programas, posiblemente situados en computadoras distintas, pueden intercambiarse cualquier flujo de datos, generalmente de manera fiable ordenada. !os sockets permiten implementar una arquitectura cliente"ser#idor. $n esta arquitectura la comunicaci%n siempre es iniciada por uno de los programas que se denomina programa cliente. $l segundo programa se encuentra a la escuc&a de peticiones entrantes con el fin de ser#ir alg'n ser#icio, por este moti#o se denomina programa ser#idor. (n socket queda definido por una direcci%n )P, un protocolo escribir informaci%n coordinadamente. Para trabajar con sockets en +ambas es necesario crear una referencia al componente de redes gb.net. $sta referencia la creamos desde Pro ecto ,,,- Propiedades . All seleccionamos la solapa .omponentes en el listado tildamos gb.net, tal cual se obser#a a continuaci%n. un n'mero de puerto. $stos par*metros el programa cliente puedan leer

configuran las condiciones necesarias para que el programa ser#idor

.omo resultado obtenemos una nue#a categora en la caja de &erramientas, /et0ork:

Para en#iar un mensaje de una computadora a otra debemos desarrollar dos programas diferentes. (no denominado ser#idor otro denominado cliente. $l ser#idor siempre estar* esperando recibir una solicitud de cone1i%n de otro programa, el cliente. Aplicaciones Cliente/Servidor !as aplicaciones que trabajan en una red 2 a sea en una !A/ o en )nternet3 se basan en la arquitectura cliente"ser#idor. $sta arquitectura consiste en una aplicaci%n principal, que ofrece un ser#icio 2ser#idor3 se mantiene a la espera de que una aplicaci%n cliente se conecte solicitando una determinada cientos de informaci%n. $n este tipo de arquitectura es com'n tener un 'nico programa ser#idor aplicaciones clientes que reali4an peticiones para establecer una cone1i%n. Servidor: $s toda aplicaci%n que se mantiene a la espera de que un cliente solicite informaci%n, la cual ser* entregada si el ser#idor as lo desea. Se dice que este ofrece o sir#e un ser#icio. Cliente: $s toda aplicaci%n que se conecta a un ser#idor para solicitarle alguna informaci%n. (n claro ejemplo de una aplicaci%n cliente"ser#idor es el .iber.ontrol, que a tra#5s de un programa ser#idor permite controlar una gran cantidad de programas clientes.

Controles ServerSocket y Socket $stos controles permiten reali4ar cone1iones cliente"ser#idor a tra#5s del protocolo 6.P. $l Ser#erSocket se comporta como un ser#idor se socket, es decir, se encuentra a la escuc&a de peticiones de clientes remotos o locales 2dos aplicaciones en una misma computadora tambi5n se pueden comunicar3 a tra#5s de un determinado puerto. !os puertos se enumeran del 7 al 899:9. !os puertos del 7 al 7;<= se consideran reser#ados por otros ser#icios no es recomendable utili4arlos. $l control socket es el que estar* en la aplicaci%n cliente es quien solicitar* la cone1i%n al ser#idor

ubic*ndolo por su n'mero de )P contact*ndolo por el puerto en donde este escuc&ando.

Programa Cliente:

Al iniciar la aplicaci%n cliente los botones >esconectar $n#iar deber*n estar des&abilitados, a que no e1iste cone1i%n con ser#idor alguno.
PUBLIC SUB Form_Open() Button2.Enabled = FALSE Button3.Enabled = FALSE END

!a primera acci%n a reali4ar,

fundamental para toda aplicaci%n de este tipo, es crear la cone1i%n al

ser#idor, a que solo se puede transmitir informaci%n si la cone1i%n cliente"ser#idor se encuentra acti#a. Propiedades necesarias del control Socket: , ?ost: Asignamos la direcci%n a la que deseamos conectar 2puede ser el nombre de la P. o su n'mero de )P3. $ste #alor ser* ingresado en 6e1t@o17. , Port: Asignamos el puerto al que deseamos conectar con el Ser#idor. $s el n'mero de puerto en que est* escuc&ando el programa ser#idor. $ste #alor ser* ingresado en 6e1t@o1<. M5todos necesarios del control Socket: , .onnect: .onecta al Ser#idor. Ser* codificado en el bot%n .onectar 2@utton7 en este caso3. A continuaci%n la programaci%n del bot%n .onectar, que debe ejecutar, como se &a dic&o, el m5todo .onnect23:
PUBLIC SUB Button1_Click() Socket1.Host = Te tBo 1.Te t Socket1.!ort = "al#Te tBo 2.Te t$ Socket1.Connect#$ Button1.Enabled = FALSE Button2.Enabled = TRUE END

$n las primeras dos lneas asignamos los datos de cone1i%n al ser#idor remoto, como son la )P o >/S 2?ost3 n'mero de puerto 2Port3. !uego llamamos al m5todo .onnect para reali4ar la cone1i%n cambia, mos el estado de los botones. Si la cone1i%n se reali4a con 51ito el control Socket dispara el e#ento Aead 23, aqu es donde podemos re, ali4ar acciones inmediatas en el momento preciso en que se logra establecer la cone1i%n con el ser#idor. $n este caso #amos a informar en el 6e1tArea7 el 51ito de la cone1i%n nectar.
PUBLIC SUB Socket1_%ead&()
Te t'rea1.te t = Te t'rea1.Te t Socket1.-ocal!ort ( .b./e0line ( )Cone i*n e itosa con Ser+idor , ) ( Socket1.-ocalHost ( ),) (

&abilitamos el bot%n $n#iar

>esco,

Button1.Enabled = FALSE Button2.Enabled = TRUE Button3.Enabled = TRUE END

6ambi5n &a que tener presente que en cualquier momento el ser#idor nos puede cerrar la cone1i%n, o bien cerrarse por alg'n error. Para ello contamos con el e#ento .losed23, que es disparado por el control Socket al perder la cone1i%n con el ser#idor ser* informado de la siguiente manera:
PUBLIC SUB Socket1_Closed() Te t'rea1.te t = Te t'rea1.Te t Button1.Enabled = TRUE Button2.Enabled = FALSE Button3.Enabled = FALSE END ( )Cone i*n cerrada por el Ser+idor.) ( .b./e0-ine

$n cambio, si queremos cerrar nosotros mismos la cone1i%n con el ser#idor basta con cerrar el control Socket cuando se presione el bot%n >esconectar 2@utton<3.
PUBLIC SUB Button2_Click() CLOSE Socket1 Te t'rea1.Te t = Te t'rea1.Te t ( )Cone i*n cerrada por el Cliente) ( .b.ne0line Button1.Enabled = TRUE Button2.Enabled = FALSE Button3.Enabled = FALSE END

Solo resta programar nuestro .liente para en#iar un arc&i#o:

recibir datos. .uando se reciben datos el control

Socket dispara el e#ento Aead23, desde all podemos leer los datos de la misma manera que se lo &ace con

PUBLIC SUB Socket1_%ead() DIM %ecibido 'S Strin. IF Socket1.Status = /et.Connected THE/ READ 1Socket12 %ecibido2 -o3#Socket1$ Te t'rea1.Te t = Te t'rea1.Te t ( )Ser+idor 4445 ) ( %ecibido ( .b./e0-ine END IF END

Para en#iar datos al ser#idor lo &acemos bas*ndonos en la escritura de arc&i#os, en este caso escribiendo en el Socket como si se tratase de un arc&i#o. $sto se ejecutar* cada #e4 que se pulse el bot%n $n#iar 2@utton:3.

PUBLIC SUB Button3_Click() IF Socket1.Status = /et.Connected THEN WRITE 1Socket12 Te t'rea2.Te t2 -en#Te t'rea2.Te t$ Te t'rea1.Te t = Te t'rea1.te t ( )Cliente 4445 ) ( Te t'rea2.Te t ( .b.ne0line Te t'rea2.Te t = )) END IF END

Por ultimo, podemos utili4ar el e#ento $rror para detectar cualquier problema de cone1i%n. $n caso que ocurra uno, procedemos a cerrar la cone1i%n e informar al usuario sobre dic&o error:
PUBLIC SUB Socket1_Error() SELECT CASE Socket1.Status CASE /et.CannotCreateSocket 6essa.e.Error#)El sistema no permite crear un socket)$ CASE /et.Host/otFound 6essa.e.Error#)Host no encontrado)$ CASE /et.Connection%e3used 6essa.e.Error#)/o es posible conectar. -a solicitud 3ue rec7a8ada)$ CASE /et.Cannot%ead 6essa.e.Error#)Error le&endo datos)$ CASE /et.Cannot9rite 6essa.e.Error#)Error escribiendo datos)$ END SELECT Button1.Enabled = TRUE Button2.Enabled = FALSE Button3.Enabled = FALSE END

Antes de dar por finali4ada la aplicaci%n, es recomendable cerrar el socket si es que esta acti#o al momento de cerrar el formulario.
PUBLIC SUB Form_Close#$ IF Socket1.Status = /et.'cti+e THEN CLOSE Socket1 END IF END

>e esta manera el programa .liente est* terminado, para probarlo es necesario crear el programa Ser#idor. Pero mientras tanto es posible probarlo con un ser#idor 0eb, por ejemplo google. Para ello iniciamos el programa conectamos con 000.google.com.ar 2>/S3, el puerto designado para transferencia de p*ginas 0eb es el B;. >e esta manera podemos #erificar si nuestra aplicaci%n es capa4 de conectarse o no con una aplicaci%n remota.

Programa Servidor:

$l programa ser#idor es una aplicaci%n totalmente independiente de la aplicaci%n cliente, por lo cual &abr* que abrir un nue#o pro ecto en +ambas diseCar el formulario propuesto. Al iniciar el ser#idor los botones >esconectar encuentra acti#o con cone1iones aceptadas.
PUBLIC SUB Form_Open() Button2.Enabled = FALSE Button3.Enabled = FALSE END

$n#iar deber*n estar des&abilitados, a que no se

$l siguiente paso ser* &abilitar el control Ser#erSocket para que pueda atender cone1iones entrantes, es decir, dejarlo Da la escuc&aD. Para esto necesitamos un bot%n D$scuc&arD un n'mero de puerto local 2a elecci%n, siempre cuando no sea un puerto reser#ado3 por donde deseamos recibir cone1iones entrantes. Propiedades necesarias: ,6 pe: $specificamos el protocolo de comunicaci%n, en nuestro caso #a 6.P. ,Port: Asignamos el puerto local por donde deseamos recibir cone1iones. M5todos necesarios: , !isten: $scuc&a peticiones entrantes. , .lose: .ierra el Ser#erSocket, desatendiendo de esta manera las solicitudes de los clientes. $#entos in#olucrados: , .onnectionAequest23: Ecurre cuando un .liente solicita una cone1i%n al Ser#idor. , SocketF.losed23: Ecurre cuando el .liente cierra la cone1i%n, no es disparado por el control Ser#erSocket. , $rror23: Ecurre en caso de errores.

)niciamos entonces la codificaci%n con el bot%n escuc&ar, que debe llamar al m5todo !isten.
PUBLIC SUB Button1_Click() Ser+erSocket1.T&pe = /et.:nternet Ser+erSocket1.!ort = "al#Te tBo 1.Te t$ Ser+erSocket1.-isten#$ IF Ser+erSocket1.Status = /et.'cti+e THEN Button1.Enabled = FALSE Button2.Enabled = TRUE END IF END

Te t'rea1.Te t = )Ser+idor acti+o a la escuc7a de cone iones entrantes) ( .b./e0-ine

.omo se obser#a la primera acci%n es indicar el protocolo de cone1i%n, /et.)nternet &ace referencia al protocolo 6.P sobre el cu*l se apo a internet. !uego se indica el puerto por donde entrar*n las cone1iones remotas finalmente el m5todo !isten lo &ace operati#o. ?asta aqu el Socket s%lo esta Descuc&andoD cone1iones. .uando un cliente intenta conectarse el Ser#erSocket dispara el e#ento .onnection23, en donde podemos aceptar o rec&a4ar la cone1i%n como se lo &ace a continuaci%n.
PUBLIC SUB Ser+erSocket1_Connection#%emoteHost:! AS Strin.$ Socket'ceptado = Ser+erSocket1.'ccept#$

Te t'rea1.Te t = Te t'rea1.Te t ( )Cone i*n solicitada por ,) ( %emoteHost:! ( .b./e0-ine

Te t'rea1.Te t = Te t'rea1.Te t ( )Conectado con ) ( Socket'ceptado.%emoteHost ( ),) ( Socket'ceptado.%emote!ort ( ) por puerto local ) ( Socket'ceptado.-ocal!ort ( .b.ne0line

Button3.Enabled = TRUE END

(na cosa resalta del c%digo anterior, al aceptar la cone1i%n se crea una instancia de un nue#o objeto que representa la cone1i%n con el cliente. $ste objeto debe e1istir a lo largo de nuestro pro ecto, por lo cual es necesario definir esta #ariable como publica del formulario. !o &acemos en el inicio del c%digo:
PUBLIC Socket'ceptado AS Ob;ect

A esta altura a estamos en condiciones de aceptar cone1iones de clientes. .uando un cliente se intenta conectar por nuestro puerto, el Ser#erSocket lo detectar* generar* el e#ento .onnection23. $n ese momento podemos identificar al cliente por su )P, que se encuentra en el parametro Aemote?ost)P. A continuaci%n #amos a codificar el bot%n desconectar para anular la cone1i%n con el programa cliente:
PUBLIC SUB Button2_Click#$ Ser+erSocket1.Close#$ Button1.Enabled = TRUE Button2.Enabled = FALSE Button3.Enabled = FALSE END

Te t'rea1.Te t = Te t'rea1.Te t ( )-a cone i*n 3ue cerrada por el ser+idor.) ( .b.ne0line

!os objetos Socket 2Ser#erSocket SocketF.losed23:

Socket3 tienen un gestor de e#entos, justamente llamado Socket, es

por esto que, para detectar el cierre de la cone1i%n por parte del cliente, lo &acemos desde el e#ento

PUBLIC SUB Socket_Closed#$ Te t'rea1.Te t = Te t'rea1.Te t ( )El cliente cerr* la cone i*n.) ( .b./e0-ine END

Solo resta programar nuestro ser#idor para en#iar generado por el gestor de e#entos Socket:

recibir los datos que pro#ienen del objeto

SocketAceptado. !o &acemos como si el objeto SocketAceptado fuese un arc&i#o, a tra#5s del e#ento Aead

PUBLIC SUB Socket_%ead#$ DIM %ecibido AS Strin. READ #Socket'ceptado2 %ecibido2 -o3#Socket'ceptado$ Te t'rea1.Te t = Te t'rea1.Te t ( )Cliente 4445 ) ( %ecibido ( .b./e0-ine END

Para en#iar datos

programamos el bot%n $n#iar 2@utton:3 tambi5n considerando el objeto

SocketAceptado como si fuese un arc&i#o.


PUBLIC SUB Button3_Click#$ WRITE #Socket'ceptado2 Te t'rea2.Te t2 -en#Te t'rea2.Te t$ Te t'rea1.Te t = Te t'rea1.te t ( )Ser+idor 44445 ) ( Te t'rea2.Te t ( .b.ne0line Te t'rea2.Te t = )) END

Por ultimo podemos utili4ar el e#ento error para detectar cualquier problema de cone1i%n. $n caso que ocurra uno podemos cerrar la cone1i%n e informar al usuario de dic&o error:
PUBLIC SUB Ser+erSocket1_Error#$ 6essa.e.Error#)Error en el Ser+idor de Socket)$ CLOSE Ser+erSocket1 END

>e esta manera el programa ser#idor est* terminado listo para probarlo junto al programa cliente.

Pablo Mileti pablomiletiGgmail.com

You might also like