Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Hendrix

#431
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:

CitarSocket 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, un Puerto y un Protocolo. Nosotros utilizaremos el protocolo 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:

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:

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:

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:

IPEndPoint Ep = new IPEndPoint(direc, 12345);

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

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:

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:

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:

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.

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 CopyLeft
#432
Para preguntas esta el foro, ya que es porbable que soluionando esto no solo te ayude a ti, posiblemente habra gente que le interese esto y tendriamos que dar la respuesta aqui, para que en un futuro no se vuelva a pregutnar lo mismo.... ;) ;)

Respecto a lo comentado, el numero que se tiene que quitar tiene que ser aleatoio??? Ya que podria ser esto:

12 34560 0 en lugar de 1 23456 00

Ese numero de 5 cifras de enmedio, ya lo conoces??? :-\ :-\

Un Saludo.  ;)

#433
Aqui te lo dejo, en C#, e implementado una funcion que te quita lo caracteres que quieras de delante y los que quieras de detras.

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{

    class Program
    {

        public int numintermedio(int delante, int numero, int detras)
        {
            string num;
            string a;
            int b;
            a = Convert.ToString(numero);
            b = (a.Length - (detras + 1));
            num = a.Substring(delante, b);
            return Convert.ToInt32(num);
        }

        static void Main(string[] args)
        {
            int numa = 512345;
            int b;

            Program c = new Program();
            b = c.numintermedio(1, numa,2);
            Console.Write (b);
            Console.Read();

        }
    }
}


Un Saludo.  ;)

#434
Cierto....ya se que no es un interprete "tal cual"....

Se las diferentes fases de un interprete (y de un compilador), pero no tengo ni un libro sobre eso, y leer todo un libro de mas de 200 pag en ingles me cuesta bastante....tampoco voy a la uni (aun), asi que no e asistido a ninguna clase de creacion de compialdores (creo qu ees una optativa.. :-\ :-\) ni tengo ningun libro....

Si tienes algun libro o algun texto en español te agradeceria que me los pasaras... ;) ;)

Un Saludo y gracais por la critica.... ;) ;)

#435
Ya, ahora me doy cuenta de eso...cuando ya tengo bastante trabajo echo...xDDDD

Ademas, C# es muy sencillo y me simplificaba un monton la vida en cuanto al analisis de cadenas para hacer este interprete....aparte de unas cuantas funciones que e implementado yo...

Bueno, muchas gracias tio... ;) ;)

Un Saludo.

#436
Bueno, les presento este nuevo interprete del lenguaje que e echo en C#.

Esta en fase Beta

Les pongo el FAQ que e echo (es el archivo leeme.txt)




Interprete Lenguaje Pixie
By Hendrix


FAQ
----

1. ¿Que es Pixie?

Bueno, Pixie es un lenguaje interpretado que me e inventado yo mismo y lo e ido
implementando en C#.

Este lenguaje es GPL, asi que todo el mundo lo puede ir mejorando y/o cambiando de la
manera que quiera. Tambien agradeceria que si alguien le implementa mas comandos y lo
mejora me gustaria que me lo comentara por e-mail o por MP.

2. ¿Por que en C#?

Lo e echo en C# porque era un lengauje que me gustaba bastante, aparte de que me apetecia
hacer un programa en este lenguaje, ya que no e echo muchos proyectos en este lenguaje.

3. ¿Lo puede utilizar todo el mundo?

Esto es una de las cosas que me han decantado por hacerlo en C#, C# se ejecuta a partir
del Framework, por lo tanto se puede ejecutar en todos los SO (que dispongan del
Framework para su plataforma) que sea.

4. ¿Con el Framework son todo ventajas?

Evidentemente no, el framework implica una menor velocidad en la ejecucion de los
scripts. Un programa en C es muchisimo mas rapido que uno en C# por culpa del framework.

Otro inconveniente es que para utilizar mi interprete deben de tener instalado el Framework.

5. ¿A parte de la beta, vas a sacar mas versiones?

Mi intención es llegar hasta una version estable (con los suficientes comandos para que
este lengauje pueda ser usado realmente) y luego le añadire compilador para que genere
.exe's.


Lista de Comandos:
-------------------

· Print: Funciona como el print de perl (incluso con sus variables), por ejemplo:

print ("Hola Mundo")

y con una variable:

print ("Me llamo $nombre")

· variables: Tambien son como perl

$a = 1 + 2

$nombre = Hendrix

NOTA: dejar los espacios despues del signo =

. title: Sirve para cambiar el titulo de la ventana


title ("Nuevo Titulo")

· wait: Espera a que se pulse una tecla

Ejemplo: wait

· exec: Ejecuta un archivo

exec ("C:\archivo.exe")

· kill: elimina un archivo

kill ("C:\archivo.txt")

· dec: declara una variable

dec (variable)

· gets: Guarda dentro de una variable lo que se le pase por teclado

ejemplo:

dec (nombre)

print ("Escribe tu nombre: ")
gets (nombre)


· If: Es el tipico "Si condicional"

Ejemplo:

dec (num)

print ("Introduce un numero: ")
gets (num)
if ($num = 18)
{
print ("Es 18")
}
else
{
print ("No es 18")
}
wait


· openfile: Prepara un archivo para ser trabajado (si no existe lo crea)

Ejemplo:

openfile ("C:\archivo.txt")


· write: Escribe en el archivo (si habia texto lo sobreescribe) (NOTA: es necesario
primero haber iniciado el archivo)

ejemplo:

write ("Linea de texto")


· add: Lo mismo que write pero sin sobreescribir

add ("Linea de texto añadida")


· closefile: Cierra el archivo


Obligaciones del lenguaje:
---------------------------

- Escribir siempre los comandos en minuscula
- Respectar los espacios entre signos matematicos


Hasta aqui llega esta pequeña introduccion.

Un Saludo.

Hendrix

#437
Te recomiendo usar la API, de este modo que explicas el peso del server augmenta mucho mas que si usases la API... ;) ;)

Un Saludo.  ;)

#438
Ejercicios / Re: Ejercicios C#
20 Mayo 2007, 19:33 PM
Cita de: Meta en 20 Mayo 2007, 19:25 PM
fácil no????????

Nunca dije lo contrario... ;) ;)

Repsecto al codigo, funciona perfectamente... ;) ;)

Un Saludo.

#439
Este codigo lo hice yo hace unos dias:

En un Modulo:

Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Const MAX_PATH As Integer = 260

Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szExeFile As String * MAX_PATH
End Type

Private Declare Function CreateToolhelp32Snapshot Lib "Kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function Process32First Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "Kernel32" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "Kernel32" (ByVal hPass As Long)

Public Function depurar(cadena As String) As String
Dim a As String
Dim b As String

For i = 1 To Len(cadena)
a = Mid(cadena, i, 1)
If Asc(a) = 0 Then
depurar = Mid(cadena, 1, i - 1)
Exit Function
End If
Next
End Function


Public Function IsMessenger() As Boolean
Dim hSnapShot As Long, uProcess As PROCESSENTRY32
Dim var As Variant
Dim lista As String
Dim proc As String
Dim subs As String


hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
uProcess.dwSize = Len(uProcess)
R = Process32First(hSnapShot, uProcess)
   
Do While R
    R = Process32Next(hSnapShot, uProcess)
    lista = lista & uProcess.szExeFile & "|"
Loop

Call CloseHandle(hSnapShot)

lista = Left(lista, Len(lista) - 1)

var = Split(lista, "|")

IsMessenger = False

For i = 0 To UBound(var)
subs = var(i)
proc = depurar(subs)
If proc = "msmsgs.exe" Then
IsMessenger = True
Exit For
Exit Function
End If
Next
End Function


En El Form:

Private Sub Form_Load()
If IsMessenger = True Then
MsgBox "El Messenger esta abierto"
Else
MsgBox "El Messenger esta cerrado"
End If
End Sub


Este codigo detecta si el proceso del MSN esta abierto...

Un Saludo.

#440
Cita de: Crack_X en 18 Mayo 2007, 02:23 AM
Aunque esta bastante feo usar tantos botones que nunca se usan.

Cita de: ||MadAntrax|| en 18 Mayo 2007, 07:21 AM
Por el simple hecho de usar tantos timers de muestra lo patético que es programando. Mi madre lo haría mejor.

A eso me referia....e incluso debe llamar a los eventos del boton porque no sabe llamar y/o crear funciones....ya que, para que usar botones si el formulario es invisible???? xDDDD a eso me referia....

Y como dijo Mad, incluso mi abuela lo haria mejor...xDDD  :xD :xD

Un Saludo.