Ver Mensaje Individual
  #145 (permalink)  
Antiguo 02/01/2008, 03:00
chcma
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Re: FAQ´S del foro de Net

TEMA: CONEXION SOCKETS
PREGUNTA: COMO HACER UNA CLASE SIMPLE DE UN SERVIDOR DE SOCKETS
RESPUESTA:
Bueno, como yo, seguro que a muchos os gustan los sockets y que muchos habeis tenido problemas o no habeis sabido por donde empezar con el asunto... Aqui dejo una pequeña clase, a la cual le falta mucho por matizar, pero con la que podreis empezar seguro.

Un saludo.

Código:
using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;
using System.Reflection;
namespace HeviaServerXml
{
    public class ClsServidor
    {
        /// <summary>
        /// Puerto donde escucha el servidor
        /// </summary>
        private int _puertoEscucha = 0;
        /// <summary>
        /// Ip donde esta presente el servidor
        /// </summary>
        private string _ipEscucha = string.Empty;
        /// <summary>
        /// Rango de Ips donde esta presente el servidor
        /// </summary>
        private string[] _ipsEscucha = null;
        /// <summary>
        /// Indica si el servidor esta activo o no
        /// </summary>
        private bool _servidorActivo =false;

        
        private List<Socket> listaSockets = new List<Socket>();
        private Socket objSocketServidor = null;
        private byte[] bytesDatos = new byte[2048];


        #region "EVENTOS"
            public delegate void EventoDatosRecibidos(string txtIpCliente, int puertoCliente, string txtDatosRecibidos);
            /// <summary>
            /// Evento que recoge los datos recibidos
            /// </summary>
            public event EventoDatosRecibidos DatosRecibidos;

            public delegate void EventoDatosEnviados(string txtIpCliente, int puertoCliente, string txtDatosEnviados);
            /// <summary>
            /// Evento que recoge los datos enviados
            /// </summary>
            public event EventoDatosEnviados DatosEnviados;

            public delegate void EventoNuevaConexion(string txtIpCliente, int puertoCliente);
            /// <summary>
            /// Evento que se lanzara cuando se conecte un nuevo cliente
            /// </summary>
            public event EventoNuevaConexion NuevaConexion;

            /// <summary>
            /// Evento que se lanzara cuando se cierre una conexion
            /// </summary>
            public event EventHandler FinConexion;

            public delegate void EventoError(string txtMetodo, string txtError);
            public event EventoError DatosErrores;
        #endregion


        #region "CONSTRUCTORES"
            private ClsServidor()
            {

            }
            /// <summary>
            /// Constructor sobrecargado
            /// </summary>
            /// <param name="puertoEscucha">Puerto en el que escuchara el servidor</param>
            public ClsServidor(int puertoEscucha)
            {
                if (puertoEscucha < 1280)
                    throw new Exception("El puerto no puede ser menor de 1280");

                _puertoEscucha = puertoEscucha;
            }
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="puertoEscucha">Puerto en el que escuchara el servidor</param>
            /// <param name="ipEscucha">Direccion IP en el que escuchara el servidor</param>
            public ClsServidor(int puertoEscucha, string ipEscucha)
            {
                if (puertoEscucha < 1280)
                    throw new Exception("El puerto no puede ser menor de 1280");

                _puertoEscucha = puertoEscucha;
                _ipEscucha = ipEscucha;
            }
        #endregion


        #region "PROPIEDADES"
            public int PuertoEscucha
            {
                get
                {
                    return _puertoEscucha;
                }
            }

            public string IpEscucha
            {
                get
                {
                    return _ipEscucha;
                }
            }

            public string[] IpsEscucha
            {
                get
                {
                    throw new System.NotImplementedException();
                }
                set
                {
                }
            }

            public bool ServidorActivo
            {
                get
                {
                    return _servidorActivo;
                }
            }
        #endregion


        /// <summary>
        /// Metodo que inicia la escucha del servidor
        /// </summary>
        public void IniciarEscucha()
        {
            objSocketServidor = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            if(_ipEscucha != string.Empty)
                objSocketServidor.Bind(new IPEndPoint(IPAddress.Parse(_ipEscucha), _puertoEscucha));
            else
                objSocketServidor.Bind(new IPEndPoint(IPAddress.Any, _puertoEscucha));

            objSocketServidor.Listen(10);
            objSocketServidor.BeginAccept(new AsyncCallback(ConexionRealizada), null);
            _servidorActivo = true;
        }
        private void ConexionRealizada(IAsyncResult iAr)
        {
            try
            {                
                Socket objSocket = objSocketServidor.EndAccept(iAr);
                listaSockets.Add(objSocket);
                objSocketServidor.BeginAccept(new AsyncCallback(ConexionRealizada), null);
                objSocket.BeginReceive(bytesDatos, 0, bytesDatos.Length, SocketFlags.None, new AsyncCallback(DatosLlegados), objSocket);

                if (NuevaConexion != null)
                {
                    string ipClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Address.ToString();
                    int puertoClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Port;
                    NuevaConexion(ipClienteConectado, puertoClienteConectado);
                }
            }
            catch (Exception ex)
            {
                if (DatosErrores != null)
                    this.DatosErrores(MethodBase.GetCurrentMethod().Name, ex.Message);
            }
        }
        private void DatosLlegados(IAsyncResult iAr)
        {            
            Socket objSocket = (Socket)iAr.AsyncState;
            try
            {
                int tamanioDatosRecibidos = objSocket.EndReceive(iAr);
                if (tamanioDatosRecibidos > 0)
                {
                    byte[] bytesDatosReales = new byte[tamanioDatosRecibidos];
                    Array.Copy(bytesDatos, bytesDatosReales, tamanioDatosRecibidos);
                    string txtDatosReales = Encoding.ASCII.GetString(bytesDatosReales);

                    EnviarDatosTodos(bytesDatosReales);
                    
                    if (DatosRecibidos != null)
                    {
                        string ipClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Address.ToString();
                        int puertoClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Port;
                        this.DatosRecibidos(ipClienteConectado, puertoClienteConectado, txtDatosReales);
                    }
                    
                    objSocket.BeginReceive(bytesDatos, 0, bytesDatos.Length, SocketFlags.None, new AsyncCallback(DatosLlegados), objSocket);
                }
            }
            catch (Exception ex)
            {
                if (DatosErrores != null)
                    this.DatosErrores(MethodBase.GetCurrentMethod().Name, ex.Message);
            }
        }


        private void EnviarDatosTodos(byte[] bytesMensaje)
        {
            foreach (Socket objSocket in this.listaSockets)
            {
                EnviarDatos(objSocket, bytesMensaje);
            }
        }
        private void EnviarDatos(Socket objSocket, byte[] bytesMensaje)
        {
            objSocket.BeginSend(bytesMensaje, 0, bytesMensaje.Length, SocketFlags.None, new AsyncCallback(DatosEnviadosAr), new Object[] { objSocket, bytesMensaje });
        }
        private void DatosEnviadosAr(IAsyncResult iAr)
        {
            Object[] objDatos = (Object[])iAr.AsyncState;
            Socket objSocket = (Socket)objDatos[0];
            byte[] bytesEnviados = (byte[])objDatos[1];

            objSocket.EndSend(iAr);

            string ipClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Address.ToString();
            int puertoClienteConectado = ((IPEndPoint)objSocket.RemoteEndPoint).Port;
            string txtDatosEnviados = Encoding.ASCII.GetString(bytesEnviados);


            if (this.DatosEnviados != null)
                DatosEnviados(ipClienteConectado, puertoClienteConectado, txtDatosEnviados);
        }
    }
}
__________________
Charlie.

Última edición por chcma; 02/01/2008 a las 05:59 Razón: Actualización del post