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.
Remoting o Serialización :P
Saludos
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.
Muchísimas gracias a ambos :)
Voy a echarle un vistazo más detenidamente, pero tiene muy buena pinta.
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í:
ÿÿÿÿ =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:
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.
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Data.SqlTypes;
namespace Cliente
{
class Program
{
static void Main(string[] args)
{
RunClient("127.0.0.1", 6666);
}
public static void RunClient(string SrvIP, int SrvPort)
{
object obj = null;
XmlSerializer xmls = new XmlSerializer(typeof(Employee));
try
{
var tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect(SrvIP, SrvPort);
Console.WriteLine("Connected");
Stream stm = tcpclnt.GetStream();
Employee mp = new Employee();
mp.EmpId = 10;
mp.EmpName = "Omkumar";
byte[] b = new byte[10000];
Stream st = new MemoryStream(b);
Console.WriteLine("Enviando Informacion...");
xmls.Serialize(st, mp);
stm.Write(b, 0, b.Length);
var bb = new byte[10000];
var k = stm.Read(bb, 0, bb.Length);
for (var i = 0; i < k; i++)
Console.Write(Convert.ToChar(bb[i]));
Console.ReadLine();
tcpclnt.Close();
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
Console.ReadLine();
}
}
}
}
Código para el Servidor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Data.SqlTypes;
namespace Servidor
{
class Program
{
static void Main(string[] args)
{
RunServer("127.0.0.1",6666);
}
public static void RunServer(string SrvIP, int SrvPort)
{
try
{
var ipAd = IPAddress.Parse(SrvIP);
XmlSerializer xmls = new XmlSerializer(typeof(Employee));
/* Initializes the Listener */
if (ipAd != null)
{
var myList = new TcpListener(ipAd, SrvPort);
/* Start Listening at the specified port */
myList.Start();
Console.WriteLine("El servidor se está ejecutando en el puerto: " + myList.LocalEndpoint);
Console.WriteLine("Esperando conexion...");
var hacen = new ASCIIEncoding();
Employee mp = null;
while (true)
{
Socket s = myList.AcceptSocket();
Console.WriteLine("Conexion aceptada de: " + s.RemoteEndPoint);
var b = new byte[10000];
Stream stream = new MemoryStream(b);
int k = s.Receive(b);
Console.WriteLine("Informacion recibida. Deserializando...");
mp = (Employee)xmls.Deserialize(stream);
stream.Close();
Console.WriteLine("Deserializado correcto");
s.Send(hacen.GetBytes("Mensaje recibido"));
Console.WriteLine("Employee Id: {0}", mp.EmpId.ToString());
Console.WriteLine("Employee Name: {0}", mp.EmpName);
s.Close();
Console.ReadLine();
}
myList.Stop();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
}
}
}
Este es el codigo para la clase que ambos programas deben de tener:
using System;
namespace Cliente
{
[Serializable()] //Set this attribute to all the classes that you define to be serialized
public class Employee
{
public int EmpId;
public string EmpName;
//Default constructor
public Employee()
{
EmpId = 10;
EmpName = "Periquito";
}
}
}
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.
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...!!!