Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Hendrix en 26 Mayo 2007, 16:20 pm



Título: [Tutorial] Sockets en C#
Publicado por: Hendrix en 26 Mayo 2007, 16:20 pm
Sockets en C#


Index:

  • Introducción
  • ¿Qué es un Socket?
  • Teoria sobre Sockets en C#
  • Programando una aplicacion Cliente-Servidor
  • Implementación del protocolo HTTP en C# mediante Sockets
  • Despedida



1. Introducción

En este tutorial voy a explicar como trabajar con sockets en C#, este tutorial puede servir tanto para C# como para VB, aunque lo centrare en C#. Recuerden que exportar un codigo en C# a otro en VB no es tan complicado.

A lo largo de este tutorial veremos que significa la palabra socket y como crearnos uno, pasaremos por un ejemplo de aplicación Cliente-Servidor hasta llegar a un ejemplo en el que con nuestra aplicacion haremos una peticion a una pagina web para que nos mande su Index.html (que es lo que hacen los navegadores).

Bueno, por ultimo apuntar que trabajaremos en modo consola, que aprticularmente me gusta más.

Ahora si, ya podemos empezar con lo que verdaderamente es el tutorial.

2. ¿Qué es un socket?

Para responder a esta pregunta, podemos consultar perfectamente la wikipedia, que siempre es de gran ayuda.

Cita de la Wikipedia:

Citar
Socket designa un concepto abstracto por el cual dos programas (posiblemente situados en computadoras distintas) pueden intercambiarse cualquier flujo de datos, generalmente de manera fiable y ordenada.

Un socket queda definido por una dirección IP, un protocolo y un número de puerto.

Es decir, es un metodo para que aplicaciones situadas en disdintos ordenadores (o no, pueden comunicarse perfectametne aplicaciones situadas en el mismo ordenador) puedan comunicarse. Para ello, se necesita la IP (http://es.wikipedia.org/wiki/IP), un Puerto (http://es.wikipedia.org/wiki/Puerto_de_red) y un Protocolo (http://es.wikipedia.org/wiki/Protocolo_de_Internet). Nosotros utilizaremos el protocolo TCP (http://es.wikipedia.org/wiki/TCP).

Basicamente al socket le pasaremos la IP a conectar, el puerto a conectar/escuchar y el protocolo, aparte de otras cosas, pero lo importante es eso.

3. Teoria sobre Sockets en C#

Este apartado es un "pasos previos" para hacer la aplicacion del siguiente capitulo.

Para inidicar que queremos trabajar con sockets, tenemos que agregar la siguientes lineas en el Using:

Código:
using System.Net;
using System.Net.Sockets;

Asi le indicamos que trabajaramos con sockets.

Para conseguir la direccion del IP se usa el IPAddress, un ejemplo y luego lo explico:

Código:
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 instrucción:

Código:
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:

Código:
IPEndPoint Ep = new IPEndPoint(direc, 12345);

Lo siguiente es crear el socket con lo obtenido hasta ahora. Lo llamaremos asi:

Código:
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 información sobre estos consultad la informacion que les da el entorno de programación.

ProtocolType.Tcp: Es el potocolo que se usara, tambien hay vario, para mas informacion consulten el entorno de programación.

Bien, una vez echo esto ya tenemos el socket apunto para ser usado. Para usarlo, vamonos directamente a la practica, es decir, al punto siguiente.

4. Programando una aplicacion Cliente-Servidor

Con lo de capitulo anterior agregado a nuestra futura aplicación, ya estamos listos para empezar a explicar todo lo que falta.

En este capitulo programaremos un servidor, con el cual nos conectaremos con el NetCat para comunicarnos con nuestra aplicación.

Al codigo que teniamos antes le agregamos estas lineas:

Código:
socket.Bind(Ep);
socket.Listen(100);

Lo que hacemos aqui es proceder a escuchar por el puerto descrito en Ep (recuerden que era el 12345). Luego en la siguiente linea, el parametro de Listen establece la longitud máxima de la cola de conexiones pendientes que puede tener el servidor antes de empezar a rechazar conexiones.

La siguiente linea a agregar es la siguiente:

Código:
Socket handler = socket.Accept();

Esta linea indica que el servidor queda esperando una llamada para leugo aceptarla.

Eso era la principal parte a explicar, ahora les pegare un codigo explicado de la aplicación que e echo:

Código:
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 conexión"); //Avisamos qde 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

5. Implementación del protocolo HTTP en C# mediante Sockets

En este capítulo implementaremos un Cliente, el cual va a pedir a una pagina web que le transfiera el index de su pagina. Les pondre todo el codigo de mi Cliente comentado.

Código:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string cabecera = "GET /index.html HTTP/1.0\n\n"; //Cabecera para hacer la peticion del index.
            string respuesta;
            Byte[] SendBytes = Encoding.ASCII.GetBytes(cabecera);
            Byte[] RecvBytes = new Byte[255];
            int bytes;
            bool semaforo;
            string html = "";
            int e;

            semaforo = false;

            IPHostEntry address = Dns.GetHostEntry("www.web.com");

            IPEndPoint Ep = new IPEndPoint(address.AddressList[0], 80);

            Socket socket = new Socket(AddressFamily.InterNetwork,
                                         SocketType.Stream,
                                         ProtocolType.Tcp);

            try
            {

                socket.Connect(Ep); //Conectamos

                socket.Send(SendBytes,SendBytes.Length,SocketFlags.None); //Enviamos la cabecera

                bytes = socket.Receive(RecvBytes,RecvBytes.Length,SocketFlags.None); //Recibimos la respuesta en bloques de 255 bytes

                respuesta = Encoding.ASCII.GetString(RecvBytes, 0, bytes); //Codificamos la respuesta

                while (bytes > 0)
                {

                    bytes = socket.Receive(RecvBytes,
                                             RecvBytes.Length,
                                             SocketFlags.None);

                    respuesta = Encoding.ASCII.GetString(RecvBytes, 0, bytes);

                    if (semaforo == false) //Filtro de encabezamientos
                    {
                        e = respuesta.IndexOf("<html>");
                        if (e != -1)
                        {
                            semaforo = true;
                            html = respuesta.Substring(e);
                        }
                    }
                    else
                    {
                        html += respuesta;
                    }

                }

                string fileName = "C:\\index.html"; //Guardamos lo recibido en C:\Index.html
                StreamWriter writer = File.CreateText(fileName);

                writer.WriteLine(html);
                writer.Close();

                Console.WriteLine("Archivo guardado con exito");
                Console.Read();

            }
            catch (Exception error) //Si durante el procedimiento hay error salta aqui.
            {
                Console.WriteLine("Se produció el siguiente error: " + error);
                Console.Read();
            }
        }
    }
}

6. Despedida

Bueno, hasta aqui llego este tutorial de Sockets en C#, la verdad es que son bastante faciles de manejar y son bastante completos.

Este documento lo e echo basandome en algunos textos de internet y obviamente segun mi experiencia con sokets.

Un Saludo.


Documento bajo licencia (http://argentina.indymedia.org/im/copyleft.gif) CopyLeft (http://es.wikipedia.org/wiki/Copyleft)


Título: Re: [Tutorial] Sockets en C#
Publicado por: BADBYTE-K en 3 Junio 2007, 17:31 pm
personalmente me encantan los sockets y me encantan documentos como este. 

se gano la chincheta :xD

Gracias


Título: Re: [Tutorial] Sockets en C#
Publicado por: Hendrix en 3 Junio 2007, 17:52 pm
 :xD :xD :xD

Pues muchas gracias.... ;) ;)

Un Saludo.  ;)



Título: Re: [Tutorial] Sockets en C#
Publicado por: shargon en 10 Agosto 2007, 11:04 am
muy bueno


Título: Re: [Tutorial] Sockets en C#
Publicado por: lepumin en 16 Diciembre 2007, 03:54 am
pues si esta weno el code.
pero me gustaria una breve explicacion de como hacer el socket asyncrono, pues necesito pasar mi antiguo programa en vb6 (winsock) a C# y la verdad no entiendo aun como hacer para poder usar los eventos de la clase sockets de .NET , he obtenido info de la red, pero aun no doy con algo similar al winsock1_dataarrival() , me confunde lo de delegados y asyncronoushandlers  :huh: a ver si alguien experimentado en la materia se lanza un pequeño tutorial solo para dar algunas luces  :)
Saludo2!!


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 7 Enero 2008, 02:11 am
LA verdad.

¿Podían hacer un minichat con Visual C# .net 2008 extremadamente muy sencillo?

Que el usuario sea capaz de conectarse al otro y hablarse.

Ejemplo ver imagen de abajo.

(http://i.elhacker.net/i?i=ue1cD61KMQ_z3a1zkzwNoGVo)


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 7 Enero 2008, 03:23 am
Una pregunta.

AddressFamily.InterNetwork: IPv4, dentro de poco harán ya los de IPv6.

¿Cómo se llama la del IPv6?

Estoy usando el Visual C# .net 2008 (En Inglés, el 1 de Febrero dicen que vendrá ya en español) Con esto quiero decir, que quizás la versión 2005 no venga el IPv6 y no lo puedas encontrar, pero sospecho que si se puede manipular, pero no se como se llama. Si sabes cual es el IPv6, nos lo dice, si lo deseas,c alro.

«Vía Slashdot me entero de que  IANA va a añadir registros AAAA de direcciones IPv6 a los cuatro servidores raíz de  DNS que lo han pedido a partir del 4 de febrero de este año, con lo que comienza la transición de IPv4 a IPv6. Gracias a esto varias máquinas podrán comunicarse entre sí sin usar el protocolo IPv4. A partir de ahora los desarrolladores y administradores de sistemas tendremos que ir con ojo a la hora de crear nuestras aplicaciones. ¿Están preparados vuestros sistemas y aplicaciones para usar IPv6?»

Fuente:
http://barrapunto.com/articles/08/01/04/1314238.shtml


EDIT:

Lo encontré, lo tenía en mi cara y no me di cuenta desde el principio. Se llama
AddressFamily.InterNetworkV6


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 7 Enero 2008, 23:45 pm
Hendriҳ

¿Podrías poner el código completo en la primera parte?

Para entenderlo rápido.


Título: Re: [Tutorial] Sockets en C#
Publicado por: Hendrix en 8 Enero 2008, 16:00 pm
Es el codigo completo.... :-\


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 9 Enero 2008, 02:58 am
Me refiero el código completo de una pasada como hisciste con el segundo sobre html.


Título: Re: [Tutorial] Sockets en C#
Publicado por: Hendrix en 9 Enero 2008, 15:51 pm
No lo tengo ya que formatee...pero es simplemente agregar ese codigo al que de ta por defecto el IDE del C#.


Título: Re: [Tutorial] Sockets en C#
Publicado por: lokidelinfierno en 29 Mayo 2008, 22:34 pm
hendri me podrias decir como puedo aplicar sokets en los formularios de windows, q simplemente no lo cacho bien a los codigos, ay porfa si me puedes brindar un codigo con un ejemplo sencillo para resivir un mensaje en un label(o lo q cayga) desde otra pc q envia el mensaje de una text box :laugh:


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 18 Marzo 2009, 01:21 am
Hola:

Tengo la idea de hacer dos programas en cada PC controlado mediante Internet y puerto serie.

1- EL PC1 hago la Interfaz de control para controlar por vía Internet mediante button (botones) el otro programa del PC que ahí está el PIC16F84A.

2- El PC2 tiene otro programa o Interfaz que puede controlar el puerto serie donde está conectado el PIC. Se controla como puedes ver en este vídeo...

http://www.youtube.com/watch?v=niWAbQ-HVnY (http://www.youtube.com/watch?v=niWAbQ-HVnY)

...con la diferencia que yo lo quiero hacer mediante control por IP y que ustedes sean capaces de controlarlo desde sus casas mientras ves como se mueve una webcam por poner un ejemplo.

Ahora la pregunta. ¿Con Visual C# se puede hacer esto?

Aquí hay un ejemplo directo de una Interfaz básico con su código fuente, conectado al puerto serie. En realidad esta Interfaz no tiene que ir con el puerto serie, sólo la conexión a Internet mediante una IP que debemos conocer para poder llegar al PC2 que si se puede conectar al puerto serie.

Las órdenes a enviar al PC2 para el puerto serie es algo parecido a esto.

Código
  1.            byte[] mBuffer = new byte[1];  
  2.            mBuffer[0] = 0x20; //ASCII letra "Espacio".  
  3.            serialPort1.Write(mBuffer, 0, mBuffer.Length);

(http://electronicapic.iespana.es/cs/pc1.jpg)

(http://electronicapic.iespana.es/cs/pc2.jpg)


Necesito información y cómo se programa. Poco a poco lo intentaré, al menos como se envía esta trama de bytes en hex para que lo entienda el PC2 desde el PC1. De momento sigo buscando en www.google.com (http://www.google.com)

¿Sugerencias?

Un cordial saludo.

Fuente:
http://foro.elhacker.net/net/controlar_pc_desde_otro_pc-t248849.0.html


Título: Re: [Tutorial] Sockets en C#
Publicado por: gemanet en 14 Julio 2009, 15:30 pm
te hago una consulta, yo implemente tu rutina de cliente servidor, lo unico que mantengo la conexion al server no la cierro ya que el cliente esta consultando permanentemente.

la cuestion es la siguiente: luego de muchas consultas simultaneas desde varios clientes, la aplicacion deja de recibir peticiones y no encuentro el motivo o causa de este problema. tuviste alguna dificultad en un ambiente de muchas pc's consultando simultaneamente?


Título: Re: [Tutorial] Sockets en C#
Publicado por: Novlucker en 14 Julio 2009, 16:42 pm
Aquí tienes, intenta cambiando el método de conexión por uno asyncrono  ;)

:http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c7695
:http://www.csharphelp.com/archives3/archive486.html

Saludos


Título: Re: [Tutorial] Sockets en C#
Publicado por: Erik# en 8 Septiembre 2009, 15:30 pm
El código completo quedaría algo así:

Código
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Net.Sockets;
  7.  
  8. namespace Sockets
  9. {
  10.    class Program
  11.    {
  12.        static void Main(string[] args)
  13.        {
  14.            IPAddress direc = Dns.GetHostEntry("localhost").AddressList[0];
  15.            IPEndPoint Ep = new IPEndPoint(direc, 12345);
  16.            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  17.            socket.Bind(Ep);
  18.            socket.Listen(100);
  19.            Socket handler = socket.Accept();
  20.            byte[] bytes = new byte[1024]; // array 1024 (t.byte)
  21.            int count;
  22.            String data = ""; // datos alm.
  23.            do
  24.            {
  25.                count = handler.Receive(bytes);
  26.                data = System.Text.Encoding.ASCII.GetString(bytes, 0, count);
  27.                if (data != "exit\n")
  28.                {
  29.                    Console.Write("{0}", data);
  30.                }
  31.            } while (data != "exit\n");
  32.            Console.WriteLine("Conexion finalizada");
  33.            byte[] msg = System.Text.Encoding.ASCII.GetBytes("\n\nFinalizada conexion");
  34.            handler.Send(msg);
  35.            handler.Shutdown(SocketShutdown.Both);
  36.            handler.Close();
  37.        }
  38.    }
  39. }
  40.  


Título: Re: [Tutorial] Sockets en C#
Publicado por: zerow en 3 Diciembre 2009, 14:12 pm
Falta lo más importante!!!!!!

En el código de ejemplo no se cierra el socket , dando paso libre a agujeros de seguridad y posibles errores en futuras conexiones!!!


Para ello al final del codigo y dentro de la exception
socket.close();


Título: Re: [Tutorial] Sockets en C#
Publicado por: Meta en 4 Diciembre 2009, 10:56 am
Se despistó.


Título: Re: [Tutorial] Sockets en C#
Publicado por: TheGhost(Z) en 3 Mayo 2010, 15:56 pm
Hola stoy usando el sSocket con WindosFors de VB.NET
y este es el codigo que recibe datos de un cliente:

 
Código:
Dim TCPListen As New TcpListener(IPAddress.Any, 11000)
        TCPListen.Start()

        While Not TCPListen.Pending()
            Thread.Sleep(5000)
        End While

        Dim TCP As TcpClient = TCPListen.AcceptTcpClient()
        Dim NetStream As NetworkStream = TCP.GetStream()


        Dim i As Int32
        Dim bytes(1024) As Byte
        Dim data As String = ""

        i = NetStream.Read(bytes, 0, bytes.Length)
        While (i <> 0)
            data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
            i = NetStream.Read(bytes, 0, bytes.Length)
        End While

        MsgBox(data)
        NetStream.Close()
        TCP.Close()


Título: Re: [Tutorial] Sockets en C#
Publicado por: TomaSs en 28 Julio 2010, 06:31 am
Alguien de ustedes abría decirme porque me da este error al ejecutar el código???
(http://img22.imageshack.us/img22/1496/errorvbd.jpg)

Gracias por el trabajo Hendrix! ;)


Título: Re: [Tutorial] Sockets en C#
Publicado por: [D4N93R] en 28 Julio 2010, 14:45 pm
Cual es la dirección que le estás dando a ese socket?

EDIT: Solucionado en otro post.


Título: Re: [Tutorial] Sockets en C#
Publicado por: Guidus en 12 Agosto 2010, 23:11 pm
Alguien me puede dar alguna referencia de donde encontrar informacion completa y/o basica de las librerias referentes a sockes ( using System.Net; using System.Net.Sockets; ).

Gracias y Saludos!


Título: Re: [Tutorial] Sockets en C#
Publicado por: [D4N93R] en 19 Agosto 2010, 14:32 pm
Guidus, has revisado MSDN?


Título: Re: [Tutorial] Sockets en C#
Publicado por: CATBro en 28 Octubre 2011, 22:15 pm
Tengo una duda, cual es la diferencia entre la clase IpEndPoint y la EndPoint?
 o que se esta haciendo aqui

Código:

// Initialise the IPEndPoint for the clients
        IPEndPoint clients = new IPEndPoint(IPAddress.Any, 0);

  // Initialise the EndPoint for the clients
        EndPoint epSender = (EndPoint)clients;

Saludos