Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: arenoide en 7 Septiembre 2011, 01:40 am



Título: Pasar objetos por red en C#
Publicado por: arenoide en 7 Septiembre 2011, 01:40 am
Hola, veréis,

Estoy haciendo un programa en C# que necesito que hable con otro programa que crearé para otro ordenador. De forma que mi programa cliente le mande información por red al programa servidor, y el programa servidor le conteste. Algo así como un chat, solo que necesito en vez de pasarle strings, pasarle directamente objetos que yo previamente haya predefinido en ambos. El programa servidor cogerá esos objetos, los modificará y me los mandará de vuelta.Esa sería más o menos la idea.

He estado googlelando pero no encuentro nada de pasar objetos por red.
Alguien me puede arrojar un poco de luz sobre este tema?

Muchas gracias de antemano.


Título: Re: Pasar objetos por red en C#
Publicado por: Novlucker en 7 Septiembre 2011, 03:04 am
Remoting o Serialización :P

Saludos
 


Título: Re: Pasar objetos por red en C#
Publicado por: seba123neo en 7 Septiembre 2011, 03:24 am
como dijeron, serializacion binaria seria la solución, aca un post perfecto con la solución.

c# send recive object over network? (http://stackoverflow.com/questions/2674210/c-send-recive-object-over-network)

saludos.


Título: Re: Pasar objetos por red en C#
Publicado por: arenoide en 8 Septiembre 2011, 14:44 pm
Muchísimas gracias a ambos :)

Voy a echarle un vistazo más detenidamente, pero tiene muy buena pinta.


Título: Re: Pasar objetos por red en C#
Publicado por: arenoide en 12 Septiembre 2011, 21:22 pm
Hola,

Veréis, he estado intentando seguir el siguiente link, para hacer el serializador-deserializador.
http://www.codeproject.com/KB/cs/objserial.aspx (http://www.codeproject.com/KB/cs/objserial.aspx)

Estoy probando primero serializando a archivo. Esto me está generando un fichero tal que así:
Código:
    ÿÿÿÿ          =Serializacion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   Serializacion.Employee   EmpIdEmpName    
      Omkumar

Cuando dentro de un mismo proyecto, serializo y deserializo no hay problema.

El problema está cuando intento deserializarlo desde otro proyecto de distinto nombre. Por ejemplo, el proyecto que serializa lo llamo "Serializacion" y el que deserializa "Deserializacion". Pues parece que Deserialización se lia al intentar deserializar el archivo y me lanza la siguiente excepción:
Código:
No se puede encontrar el ensamblado 'Serializacion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

y pienso que es porque dentro del archivo se ha insertado el nombre del proyecto entre otras cosas. Cómo podría hacerlo para que diera igual el nombre del proyecto de origen y que lo deserializara todo correctamente?

Alguna idea?
Muchas gracias.


Título: Re: Pasar objetos por red en C#
Publicado por: arenoide en 14 Septiembre 2011, 22:45 pm
Hola, finalmente encontré cómo enviar objetos entre 2 programas cuyos nombres sean distintos. Hay que hacerlo serializando en XML en vez de en binario, aquí dejo el código por si alguien en el futuro tiene mi mismo problema.
He seguido el siguiente link, solo que con algunas modificaciones:
http://www.codeproject.com/KB/cs/objserial.aspx (http://www.codeproject.com/KB/cs/objserial.aspx)

Código para el cliente:
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. using System.IO;
  8. using System.Xml.Serialization;
  9. using System.Data.SqlTypes;
  10.  
  11. namespace Cliente
  12. {
  13.    class Program
  14.    {
  15.        static void Main(string[] args)
  16.        {
  17.            RunClient("127.0.0.1", 6666);
  18.        }
  19.  
  20.        public static void RunClient(string SrvIP, int SrvPort)
  21.        {
  22.            object obj = null;
  23.            XmlSerializer xmls = new XmlSerializer(typeof(Employee));
  24.            try
  25.            {
  26.                var tcpclnt = new TcpClient();
  27.                Console.WriteLine("Connecting.....");
  28.                tcpclnt.Connect(SrvIP, SrvPort);
  29.                Console.WriteLine("Connected");
  30.  
  31.                Stream stm = tcpclnt.GetStream();
  32.  
  33.                Employee mp = new Employee();
  34.                mp.EmpId = 10;
  35.                mp.EmpName = "Omkumar";
  36.                byte[] b = new byte[10000];
  37.                Stream st = new MemoryStream(b);
  38.  
  39.                Console.WriteLine("Enviando Informacion...");
  40.                xmls.Serialize(st, mp);
  41.  
  42.                stm.Write(b, 0, b.Length);
  43.  
  44.                var bb = new byte[10000];
  45.  
  46.                var k = stm.Read(bb, 0, bb.Length);
  47.  
  48.                for (var i = 0; i < k; i++)
  49.                    Console.Write(Convert.ToChar(bb[i]));
  50.  
  51.                Console.ReadLine();
  52.  
  53.                tcpclnt.Close();
  54.            }
  55.  
  56.            catch (Exception e)
  57.            {
  58.                Console.WriteLine("Error..... " + e.StackTrace);
  59.                Console.ReadLine();
  60.            }
  61.  
  62.        }
  63.    }
  64. }
  65.  


Código para el Servidor
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. using System.IO;
  8. using System.Xml.Serialization;
  9. using System.Data.SqlTypes;
  10.  
  11. namespace Servidor
  12. {
  13.    class Program
  14.    {
  15.        static void Main(string[] args)
  16.        {
  17.  
  18.            RunServer("127.0.0.1",6666);
  19.        }
  20.  
  21.        public static void RunServer(string SrvIP, int SrvPort)
  22.        {
  23.            try
  24.            {
  25.                var ipAd = IPAddress.Parse(SrvIP);
  26.                XmlSerializer xmls = new XmlSerializer(typeof(Employee));
  27.  
  28.                /* Initializes the Listener */
  29.                if (ipAd != null)
  30.                {
  31.                    var myList = new TcpListener(ipAd, SrvPort);
  32.  
  33.                    /* Start Listening at the specified port */
  34.                    myList.Start();
  35.  
  36.                    Console.WriteLine("El servidor se está ejecutando en el puerto: " + myList.LocalEndpoint);
  37.                    Console.WriteLine("Esperando conexion...");
  38.  
  39.                    var hacen = new ASCIIEncoding();
  40.                    Employee mp = null;
  41.  
  42.                    while (true)
  43.                    {
  44.                        Socket s = myList.AcceptSocket();
  45.                        Console.WriteLine("Conexion aceptada de: " + s.RemoteEndPoint);
  46.                        var b = new byte[10000];
  47.                        Stream stream = new MemoryStream(b);
  48.                        int k = s.Receive(b);
  49.                        Console.WriteLine("Informacion recibida. Deserializando...");
  50.                        mp = (Employee)xmls.Deserialize(stream);
  51.                        stream.Close();
  52.                        Console.WriteLine("Deserializado correcto");
  53.                        s.Send(hacen.GetBytes("Mensaje recibido"));
  54.                        Console.WriteLine("Employee Id: {0}", mp.EmpId.ToString());
  55.                        Console.WriteLine("Employee Name: {0}", mp.EmpName);
  56.                        s.Close();
  57.                        Console.ReadLine();
  58.                    }
  59.  
  60.                    myList.Stop();
  61.                }
  62.            }
  63.            catch (Exception e)
  64.            {
  65.                Console.WriteLine("Error..... " + e.StackTrace);
  66.            }
  67.        }
  68.    }
  69. }
  70.  


Este es el codigo para la clase que ambos programas deben de tener:
Código
  1. using System;
  2.  
  3. namespace Cliente
  4. {
  5.    [Serializable()] //Set this attribute to all the classes that you define to be serialized
  6.    public class Employee
  7.    {
  8.        public int EmpId;
  9.        public string EmpName;
  10.  
  11.        //Default constructor
  12.        public Employee()
  13.        {
  14.            EmpId = 10;
  15.            EmpName = "Periquito";
  16.        }
  17.    }
  18. }
  19.  

Lo he copiado casi en el momento en que me ha funcionado, así que puede que haya código que sobre y demás, pero funcionar funciona.

Saludos.


Título: Re: Pasar objetos por red en C#
Publicado por: oz64 en 5 Noviembre 2013, 18:24 pm
Otra forma aparte de enviar objetos serializados en forma binaria entre dos programas cuyos nombres sean distintos es tener las clases para serializar  en librerias (.dll) ya q igual tenemos q tener esas clases en el servidor como en el cliente, teniendolo en forma de libreria solo nos hace falta referenciar al proyecto para su uso y asi se los puede usar sin tener el problema de los diferentes nombres en los proyectos.

Salu2...!!!