Está en la página 1de 12

Universidad Nacional Autnoma de Mxico

Facultad de Ingeniera

Arquitecturas Cliente/Servidor

Exposicin Sockets TCP En Lenguaje C#

Profesora: Macedo Reza Yazmine.


Gpo.: 01 Equipo 3. Gines Hinojosa Marisol Lpez Lpez Marcela Pamela Prez Cruz Juan Carlos Prez Valencia Ubaldo

08/09/09.

Historia de C Sharp C#

Este Lenguaje, desarrollado por Microsoft por un equipo dirigido por Andres Helsberj y Scott Wiltamuth, se diseo en especfico para la plataforma .Net como un lenguaje que permitiera a los programadores migrar con facilidad hacia .Net. Tiene sus races en Java, C y C++; adapta las mejores caractersticas de cada uno de estos lenguajes y agrega caractersticas propias. C# est orientado a objetos y contiene una poderosa bibiloteca de clases (FCL por sus siglas en Ingles; FrameWork Class Library), mejor conocida como Biblioteca de Clases de Framework, que consta de componentes preconstruidos que permiten a los programadores desarrollar aplicaciones con rapidez, adems este lenguaje es apropiado para desarrollar apliaciones de escritorio (Windows Forms), asi como Smart Clients, Aplicaciones Web (ASP .Net), Aplicaciones Mviles, entre otras. C# es un lenguaje de programacin visual controlado por eventos, en el cual se crean programas mediante el uso de un Entorno de Desarrollo Integrado (IDE Por sus siglas en Ingls; Integrated Development Environment). Con un IDE un programador puede crear, ejecutar, probar y depurar programas en C#, con lo cual se reduce el tiempo requerido para producir un programa funcional en una fraccin del tiempo que llevara sin utilizar el IDE. La plataforma .Net permite la interoperabilidad de los lenguajes: los componentes de software de distintos lenguajes pueden interactuar como nunca antes se habia hecho. Los desarrolladores pueden empaquetar incluso hasta el software antiguo para que trabaje con nuevos programas en C#. Adems, las aplicaciones en C# pueden interactuar a travs de Internet mediante el uso de estndares industriales de comunicacin como XML (eXtensible Markup Language) o el SOAP (Simple Object Access Protocol). El lenguaje de programacin C# original se estandariz atravs de la Ecma International (www.ecma-international.org) en Diciembre del 2002 como Estndar ECMA-334: Especificacin del Lenguaje C# (Ubicado en www.ecma international.org/publications/standards/Ecma-334.htm). Desde entonces, Microsoft propuso varias extensiones del lenguaje que se han adoptado comparte del estndar Ecma C# revisado. Microsoft hace referencia al lenguaje C# completo (incluyendo las extensiones adoptadas) como C# 2.0
Qu es un socket? Interfaz normalizado de comunicacin entre procesos utilizado inicialmente en la arquitectura TCP/IP. Es el extremo de una conexin entre procesos de aplicacin que se ejecutan en una red TCP/IP. Cada extremo se direcciona mediante la direccin IP o nombre DNS de la maquina y un nmero de puerto (entre 1 y 65535). Objetivo: Permitir que un proceso pueda enviar o recibir datos a travs de la red.

Ejemplo cliente-servidor TCP Secuencia de eventos Sockets TCP.

Ejemplo cliente-servidor TCP

Es un mtodo para que aplicaciones situadas en distintos ordenadores (o no, pueden comunicarse perfectamente aplicaciones situadas en el mismo ordenador) puedan comunicarse. Para ello, se necesita la IP, un Puerto y un Protocolo. Para indicar que queremos trabajar con sockets, en consola, tenemos que agregar la siguientes lineas en el Using: Cdigo: using System.Net; using System.Net.Sockets; Asi le indicamos que trabajaramos con sockets. Para conseguir la direccion del IP se usa el IPAddress Cdigo: IPAddress direc = Dns.GetHostEntry("localhost").AddressList[0]; Lo que se hace aqui es poner dentro de direc la IP de localhost, eso no se guarda ni en int ni en long ni en string, se guarda en IPAddress, para luego usarse en la siguiente instruccin: Cdigo: IPEndPoint Ep = new IPEndPoint(direccion, puerto); NOTA: Aunque se trabaje con numeros, esos numeros de la IP se tienen que pasar a IPAddress, ya que como int no lo va a tomar.

Donde direccion es lo que habiamos conseguido antes con IPAddress, y en puerto le ponemos un int que queramos, por ejemplo: Cdigo: IPEndPoint Ep = new IPEndPoint(direc, 12345); Lo siguiente es crear el socket con lo obtenido hasta ahora. Lo llamaremos asi: Cdigo: Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Dividamoslo por agrumentos: AddressFamily.InterNetwork: Esto indica que la direccion es para una IP v4 (xxx.xxx.xxx.xxx) SocketType.Stream: Es el tipo de socket, hay varios tipos, para mas informacin sobre estos consultad la informacion que les da el entorno de programacin. ProtocolType.Tcp: Es el potocolo que se usara, tambien hay vario, para mas informacion consulten el entorno de programacin. Programando una aplicacion Cliente -Servidor Programaremos un servidor, con el cual nos conectaremos con el NetCat para comunicarnos con nuestra aplicacin. Al cdigo que tenamos antes le agregamos estas lneas: Cdigo: socket.Bind(Ep); socket.Listen(100); Lo que hacemos aqu es proceder a escuchar por el puerto descrito en Ep (recuerden que era el 12345). Luego en la siguiente lnea, el parmetro de Listen establece la longitud mxima de la cola de conexiones pendientes que puede tener el servidor antes de empezar a rechazar conexiones. La siguiente lnea a agregar es la siguiente: Cdigo: Socket handler = socket.Accept(); Esta lnea indica que el servidor queda esperando una llamada para luego aceptarla. EL CODIGO COMPLETO QUEDA: Cdigo:

byte[] bytes = new byte[1024]; //Declaramos un array de bytes de longitud 1024 int count; String data = ""; //Declaramos data, que sera donde se almacenaran los datos do //Bucle Do/While { count = handler.Receive(bytes); //Recibimos los datos enviados y lo guardamos en cout. data = System.Text.Encoding.ASCII.GetString(bytes, 0, count); //Lo codificamos a cadena (ya que se envian como bytes) if (data != "exit\n") //Mientras lo recibido no sea exit + \n (es decir, exit + Intro, ya que intro tambien se envia) { Console.Write("Se a recibido: {0}", data); //Mostramos lo recibido pro pantalla } } while (data != "exit\n"); //Mientras lo recibido no sea exit + Intro se continua el bucle, si recibimos exit + intro, salimos del bucle Console.WriteLine("Se ha finalizado la conexin"); //Avisamos que se a terminado la transferencia de datos byte[] msg = System.Text.Encoding.ASCII.GetBytes("\n\nFinalizada conexion con la aplicacion"); //Codificamos de string a byte el siguiente mensage para que se pueda enviar al NetCat (Cliente) handler.Send(msg); //Enviamos el mensage al cliente handler.Shutdown(SocketShutdown.Both); //"Apagamos" los sockets handler.Close(); //Los cerramos

CONEXIN, CLIENTE SERVIDOR Para hacer un servidor necesitamos: Socket para escuchar en un puerto especifico Socket para comunicarnos con el cliente Dos funciones, para enviar y recibir mensajes

//La funcion neceista un Socket al que enviaremos el msg, y un byte[> que ocntenga el msg private static int SendData(Socket sock, byte[> data) { int total = 0; //Este es la cantidad enviada del mensaje

int size = data.Length; // Este es el tamao del mensahe int dataLeft = size; //Este es la parte del mensaje que no se ha enviado int sent; //Esto es lo que se envio en esta sesion //este sera el tamao del mensaje que epxlique arriba byte[> dataSize = new byte[4>; dataSize = BitConverter.GetBytes(size); //obtenemos los bytes de 'size' sent = sock.Send(dataSize);//enviamos el tamaom primero, un byte[> de 4 //ahora enviaremos el mensaje.... while (total < size) { //La funcuion Send nos devuelve un entero de cuanta cantidad logro enviar //Entonces mientras no se haya enviado todo el mensaje este ciclo se //ejecuta sent = sock.Send(data, total, dataLeft, SocketFlags.None); total += sent; dataLeft -= sent; } return total; //regresamos el total que enviamos }

Ahora la funcin para recibir mensajes es la siguiente, recuerden que estas 2 funciones las usaremos en el cliente y en el servidor: CDIGO

//Necesitamos un socket para recibir private static byte[> ReceiveData(Socket sock) { int totalRecv = 0; //la cantidad total recibida int recv; //la cantidad recibida individualmente byte[> dataSize = new byte[4>; //este sera el tamao del mensaje en byte[> int size; //Este sera el tamao en entero int dataLeft = 0; //Esto nos indica cuanta informacion nos falta recibir recv = sock.Receive(dataSize, 0, 4, SocketFlags.None);//recibimos el tamao size = BitConverter.ToInt32(dataSize, 0);//lo pasamos a un

entero dataLeft = size; //asigamos lo que nos falta recibir byte[> data = new byte[size>; //creamos un array de byte[> del tamao del mensaje while (totalRecv < size) { //empezamos a recibir recv = sock.Receive(data, totalRecv, dataLeft, SocketFlags.None); if (recv == 0) { //cuando se reciba 0 es que el cliente se desconecto ... //entonces rompemos el ciclo. data = Encoding.ASCII.GetBytes("exit" ); break; } totalRecv += recv; dataLeft -= recv; } return data; //regresamos el byte[> que recibimos }

Como funcionara el servidor y el cliente: El servidor lo que har es que cuando reciba una conexin enviara un mensaje de bienvenida al cliente y luego esperara mensajes del cliente.. el cliente lo que har es leer el mensaje de bienvenida y luego esperar a que el usuario escriba mensajes para enviarlos Constructor del Servidor (el Main debe de ser as): CDIGO

static void Main(string[> args) { byte[> data = new byte[1024>; //creamos un byte[> para enviar la bienvenida IPEndPoint ipep = new IPEndPoint (IPAddress.Any,9050); //Con el IpAdress.Any esuchamos en cualquier interfaz de red.. y el 9050 //es el puerto en el que escuharemos //creamos un socket de tipo internwtwork, stream y tcp Socket newsock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

try { newsock.Bind (ipep); //lo bindeamos para que se ancle al puerto especificaco } catch (SocketException) { //si aqui hay error es que ese puerto esta en uso y entonces es probable //que otra instancia de este programa ya este corriendo Console.WriteLine("Al parecer otra instancia del servidor ya esta corriendo" ); return; //si es asi damos un return para salirnos de la funcion y terminar //el programa } newsock.Listen(1); //escuchamos con el socket en el puerto especifaco Console.WriteLine("Waiting for a client..." ); Socket client = newsock.Accept(); //Esto acepta la conexion cuando recibe //una peticion... esto se queda esperando hasta que ocurra IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint; //creamos un IPEndPoint //con la informacion del cliente Console.WriteLine("Connected with {0} on port {1}", newclient.Address, newclient.Port); //imprimimos en la pantalla que se conecto un cliente string welcome = "Welcome to my test server 1.0"; data = Encoding.ASCII.GetBytes(welcome); //Codificamos a byte [> el mensaje //de bienvenida int sent = SendData(client, data); //lo enviamos con nuestra funcion, pasandole //el socket del cliente y el byte[> con el mensaje for (int m = 0; m < 2; m++) {//Este for nos sirve para leer infinitamente los mensajes que nos llegan try { data = ReceiveData(client); //Llama a recibir mensajes del socket cliente //esto se queda esperando hasta recibir un mensaje string message = Encoding.ASCII.GetString(data); //si recibimos un

//mensaje entonces lo decoficamos a un string if (message == "exit" ) //si recibimos exit nos salimos.. break; Console.WriteLine(message); //si no entonces lo imprimimos m--; //restamos al for para que sea infinito... } catch (SocketException) { Console.WriteLine("No se encontro conexion con el cliente {0}", newclient.Address); return; //si enocntramos un error es que se perido la conexion y con el return nos //salimos de la funcion } } //Damos el mensaje de que se desconecto el cliente XX con puerto XX Console.WriteLine("Disconnected from {0} on port {1}",newclient.Address,newclient.Port); //cerramos el socket del cliente client.Shutdown(SocketShutdown.Both); client.Close(); //Ceramos el socket con el que escuchamos newsock.Shutdown(SocketShutd own.Both); newsock.Close(); }

Ahora el cdigo del cliente debe de ser igual al del servidor con la nica diferencia que en el constructor Main las cosas sern diferentes. En cdigo del Constructor del cliente debe ser de la siguiente manera : CDIGO static void Main(string[> args) { byte[> data = new byte[1024>; //Cramos un byte[> para recibir el mensaje //de bienvenida del servidor int sent; //una variable que nos dice cuanto hemos enviado IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1" ), 9050); //Creamos un IPEndPoint con el ip del servidor y puerto del servidor //al que deseamos conectarnos, en este caso lo uso local

//Creamos el socket igual al del servidor Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); try { server.Connect(ipep);//Intentamos conectar el socket Console.WriteLine("Conectado con el servidor {0}", ipep.Address); } catch (SocketException) { //Si hay excepcion imprimimos error y salimos del programa con return Console.WriteLine("No se pudo conectar con el servidor {0}", ipep.Address); return; } try { data = ReceiveData(server); //Recibimos la bienvenida del servidor string stringData = Encoding.ASCII.GetString(data); Console.WriteLine(stringData); } catch (SocketException) { //Si hay error imprimios y nos salimos por que no hay conexion Console.WriteLine("No se ha encontrado conexion con el servidor {0}", ipep.Address); return; } while (true) { string message = Console.ReadLine(); //Leemos el input que queremos enviar try {//Enviamos el mensaje. sent = SendData(server, Encoding.ASCII.GetBytes(message)); } catch (SocketException) {//Si hay excepcion nos salimos pq no hay conexion Console.WriteLine("No se ha encontrado conexion con el servidor {0}", ipep.Address); return;

}//Si se ejeucta el comando exit nos salimos if (message == "exit" ) break; } //Indicamos que nos desocnectamos y cerramos el socket Console.WriteLine("Desconectando del servidor {0}", ipep.Address); server.Shutdown(SocketShutdown.Both); server.Close(); }

MESOGRAFA: http://www.foromsn.com/Version_Imprimible.php?Id=139962 http://www.elsevier.com/wps/find/bookdescription.cws_home/702348/descript ion#description http://www.solotuweb.com/vc~t~Sockets-para-conexiones-por-TCP-con-C-en-CSharp-(C)~id~7193.html http://dotnetero.blogspot.es/

También podría gustarte