Está en la página 1de 21

Direcciones IP en C #

Una de la mayores ventajas de .NET es la manera en como este maneja las


direcciones IP.Ya que NET se definen dos clases en el espacio de nombres
System.Net para tratar diversos tipos de informacin de direccin IP:



IPAdddress
IPEndPoint

IP Address:
Un objeto Direccin IP se utiliza para representar una nica direccin IP.
Este valor puede ser utilizado en cualquiera de los diferentes mtodos en
los que se necesita representar una direccin IP.

La Clase IPAddress


public IPAddress(long address)

En la prctica este mtodo es poco utilizado ya que normalmente no se


tiene el valor long de una direccin IP. Sin embargo la clase posee algunos
mtodos que nos resultarn tiles para manejar direcciones IP.
El mtodo Parse es el ms utilizado y sirve para crear una instancia de un
objeto IPAdress:


IPAddress newaddress = IPAddress.Parse("192.168.1.1");

Como vemos esto permite pasar de un formato de cadena, a un objeto


IPAddress que son los que realmente utilziamos en la prctica.

Ejemplo de la clase IPAddress


La clase IPAddress tambin provee de 4 propiedades que representan IP
especiales que pueden ser utilizados dentro de un programa:





Any: Usada para representar todas las interfaces de la mquina.


Broadcast: Usada para representar la direccin de broadcast de la red.
Loopback: Representa la interfaz de loopback.
None: Usada para no asignar ninguna de las IP del sistema.

Una forma de obtener la IP local es la siguiente:





IPHostEntry he = Dns.GetHostByName(Dns.GetHostName());
IPAddress myself = he.AddressList[0];

La Clase IPEndPoint
Es similar a la estructura sockaddr_in de UNIX. En .NET se utiliza la clase
IPEndPoint para representar la combinacin IP/Puerto.
Un IPEndPoint es utilizado para asociar a un sockets una IP y un puerto
local o para indicar la IP y el puerto al que se desea conectar. Se tienen dos
constructores que son:



IPEndPoint(long address, int port)


IPEndPoint(IPAddress address, int port)

Ambos constructores reciben la IP y el puerto, pero probablemente el ms


utilizado sea el segundo. La clase tambin posee dos propiedades Address y
Port para modificar cualquiera de los dos valores.

Construccin de Sockets
El espacio de nombres System.Net.Sockets es el que provee las clases
necesarias para trabajar con sockets. El constructor de la clase Sockets es el
siguiente:


Socket(AddressFamily af, SocketType st, ProtocolType pt)

Cada parmetro est representado por una enumeracin diferente dentro


del espacio de nombre System.Net_.Sockets namespace.
Parmetro

Valores

AddressFamily

AddressFamily.InterNetwork : Para comunicaciones IP

SocketType

SocketType .Dgram / SocketType .Stream

Protocoltype

Protocoltype.Udp / Protocoltype.Tcp

Propiedades de los Sockets


Algunas propiedades pueden ser utilzadas para obtener informacin acerca
de un sockets previamente creado:
Propiedad

Descripcin

Available

Obtiene la cantidad de bytes que estn listos para ser


ledos.

Blocking

Obtiene o establece al sockets en modo bloqueante.

Connected

Obtiene un valor que indica si el sockets est


conectado

LocalEndPoint

Obtiene el IPEndPoint local del socket.

ProtocolType

Obtiene el tipo de protocolo del sockets.

RemoteEndPoint

Obtiene el IPEndPoint remoto al que est conectado


el sockets.

SocketType

Obtiene el tipo del sockets.

Usando sockets Orientado a Conexin


Funciones en el Servidor:
Similar a los sockets en UNIX, una vez que se ha creado el sockets, se debe
de enlazar a una direccin de red, para ello utilizamos la funcin Bind:


Bind(EndPoint address)

Luego se debe de preparar el sockets para que acepte conexiones:




Listen(int backlog)

Backlog, indica el nmero de conexiones que se mantendrn encoladas en el


servidor hasta ser atendidas por el servidor.

Usando sockets Orientado a Conexin


Funciones en el Servidor:
Ahora ya estamos listos para aceptar conexiones para lo cual utilizamos el
mtodo Accept:
IPHostEntry local = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint iep = new IPEndPoint(local.AddressList[0], 8000);
Socket newserver = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
newserver.Bind(iep);
newserver.Listen(5);
Socket newclient = newserver.Accept();

Usando sockets Orientado a Conexin


Envo y recepcin una vez establecida la conexin:
Mtodo

Descripcin

Receive(byte[] data)

Recibe los datos y los coloca en data.

Receive(byte[] data, int size,


SocketFlags sf)

Recibe la cantidad de datos indicada por size


y la coloca en data.

Receive(byte[] data, int offset, int Recibe la cantidad de datos indicada por size
size, SocketFlags sf)
y la coloca en data a partir de la posicin
indicada por offset.
Send(byte[] data)

Enva los datos colocados en data.

Send(byte[] data, int size,


SocketFlags sf)

Enva la cantidad de datos indicada por size


desde data.

Send(byte[] data, int offset, int


size, SocketFlags sf)

Enva la cantidad de datos indicada por size


desde data a partir de la posicin offset.

SocketFlags.None: se suele utilizar cuando se necesite.

Usando sockets Orientado a Conexin


Funciones en el Cliente:
Una vez que el cliente cree un sockets, deber de asociarse una IP y un
puerto, sin embargo la funcin Connect, lo realiza de manera automtica.
IPAddress host = IPAddress.Parse("192.168.1.1");
IPEndPoint hostep = new IPEndPoint(host, 8000);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
sock.Connect(hostep);

El mtodo cliente se bloquea hasta que el connect retorna algn valor.

Usando sockets Orientado a Conexin


Cierre de una conexin:



Shutdown: Permite cerrar uno o ambos canales de comunicacin.


Close: Permite cerrar el sockets.

Los posibles valores de Shutdown son:


Valor

Descripcin

SocketShutdown.Both

Evita que se envan o se reciban datos por el sockets.

SocketShutdown.Receive Previene la recepcin de datos en el socket. Un RST se


enviar en caso de recibir datos adicionales
SocketShutdown.Send

Evita el envo de datos en el socket. A FIN ser enviado


despus de todo el buffer de datos restantes se enva

Una forma ordenada es:


 sock.Shutdown(SocketShutdown.Both);
 sock.Close();

Usando sockets No Orientado a Conexin


. NET utiliza la misma funcionalidad que Unix. Cuando se crea un socket
SocketType.Dgram, se debe utilizar el mtodo bind () para el cliente y el
servidor.Tampoco se utilizan los mtodos Connect y Listen.
Como no existe conexin, no se puede utilizar Send y Receive, pero en su
lugar tenemos los mtodos SendTo y ReciveFrom. Su sintaxis es identica que
la de los mtodos anteriores con la direferencia que estos reciben un ltimo
parmetro que es un IPEndPoint para saber a quien se enva o de quien se
reciben los datos.



ReceiveFrom(byte[], ref EndPoint)


SendTo(byte[], ref EndPoint)

Excepciones de Sockets en C#
Aunque no es obligatorio colocar las excepciones al trabajar con C#, esto
podra provocar que nuestros programas terminasen de manera no
controlada provocando resultados inesperados.
Todos los mtodos de la clase Sockets usan la excepcin SocketException,
por lo cual siempre ser recomendable encerrar nuestro cdigo dentro de
un sentencia try catch para manejar el error.

C# Socket Helper Classes


.NET provee como hemos visto, una interfaz avanzada para programadores,
pero tambin nos ofrece interfaces para simplificar la realizacin de
aplicaciones.
A continuacin presentaremos una pequea introduccin a estas clases pero
en futuros temas ampliaremos dicha informacin. Las clases son:




TcpClient
TcpListener
UdpClient

La Clase TcpClient
Presenta la funcionalidad necesaria para crear un cliente TCP, realiza lo
mismo que las funciones antes vistas pero con menos pasos. Se tienen 3
maneras de hacerlo:
Constructor por defecto:
TcpClient newclient = new TcpClient();
newclient.Connect("www.isp.net", 8000);

Uitlizando un IPEndPoint especfico:


IPAddress ia = Dns.GetHostByName( Dns.GetHostName()).AddressList[0];
IPEndPoint iep = new IPEndPoint(ia, 10232);
TcpClient newclient2 = new TcpClient(iep);
newclient2.Connect("www.isp.net", 8000);

La Clase TcpClient
Especificando un Host remoto:
TcpClient newclient3 = new TcpClient("www.isp.net", 8000);

Ejemplo:
TcpClient newclient = new TcpClient("www.isp.net", 8000);
NetworkStream ns = newclient.GetStream();
byte[] outbytes = Encoding.ASCII.GetBytes("Testing");
ns.Write(outbytes, 0, outbytes.Length);
byte[] inbytes = new byte[1024]; ns.Read(inbytes, 0, inbytes.Length);
string instring = Encoding.ASCII.GetString(inbytes);
Console.WriteLine(instring); ns.Close();
newclient.Close();'

La Clase TcpListener
Se tienen 3 constructores:




TcpListener(int port): Realiza un Bind sobre el puerto indicado.


TcpListener(IPEndPoint ie): Realiza un Bind sobre el IPEndPoint
TcpListener(IPAddress addr, int port): Realiza un Bind con un IPAddress
y un puerto.

Una vez que el sockets es creado se puede iniciar la escucha de clientes


(Listen) invocando el mtodo Start(). Con este objeto se tienen:



AcceptTcpClient: Acepta un nueva conexin y devuelve un objeto


Tcpclient.
AcceptSocket:Acepta una nueva conexin y devuelve un sockets.

La Clase TcpListener
Ejemplo:
TcpListener newserver = new TcpListener(9050);
newserver.Start();
TcpClient newclient = newserver.AcceptTcpClient();
NetworkStream ns = newclient.GetStream();
byte[] outbytes = Encoding.ASCII.GetBytes("Testing");
ns.Write(outbytes, 0, outbytes.Length);
byte[] inbytes = new byte[1024];
ns.Read(inbytes, 0, inbytes.Length);
string instring = Encoding.ASCII.GetString(inbytes);
Console.WriteLine(instring);
ns.Close();
newclient.Close();
newserver.Stop();

La Clase UdpClient
Los constructores UdpClient siguen el mismo formato que TcpClient ya que
permiten especificar la cantidad de informacin necesaria para crear el
socket UDP.
Constructores:




UdpClient(int port): Se crea un objeto en el puerto indicado.


UdpClient(IPEndPoint iep): Se crea un objeto en la direccin y puerto
indicado por IPEndPoint.
UdpClient(string host, int port): Se crea un objeto utilizando para ello el
nombre DNS y el puerto.

La Clase UdpClient
Ejemplo:
UdpClient newconn = new UdpClient(8000);
IPEndPoint remoteclient = new IPEndPoint(IPAddress.Any, 0);
byte[] recv = newconn.Receive(ref remoteclient);
string data = Encoding.ASCII.GetString(recv); ConsoleWriteLine("From: {0}",
remoteclient.ToString());
ConsoleWriteLine(" Data: "{0}", data);
newconn.Close();

Note que el objeto remoteclient, es inicializada a Any, ya que este valor ser
posteriormente sustituido.

La Clase UdpClient
El mtodo Send igual recibe como parmetro un IPendPoint que indica a
quien van dirigidos los datos.
Ejemplo:
UdpClient newclient = new UdpClient(8001);
IPEndPoint remotehost = new IPEndPoint(IPAddress.Parse("192.168.1.6"), 8001);
byte[] bytes = Encoding.ASCII.GetBytes("test string");
newclient.Send(bytes, bytes.Length, remotehost);
newclient.Close();