我有一个系统,我可以在Windows和嵌入式系统之间通过不同的点到点通信通道交换消息,而且完全可以作为非常标准的自定义序列化/反序列化函数完成,几乎完全由手工完成,因为这使得它很容易在Windows端的C#和嵌入的C端口之间移植。为什么我得到wcf反序列化的空数据?
现在我想添加一个大型网络上的PC之间进行通信的块。而不是做另一批相同的东西,使用TcpClient/TcpListener并跟踪重叠的消息和响应,我决定看看WCF。
在看过很多关于这里的信息以及其他文档等信息之后,我想出了一个非常简单的应用程序来交换消息,服务器包含一个接收和返回接口实例的函数,而不是一个固定的类。即使这个例子只有一种消息,因此只有一种类型是使用KnownType和ServiceKnownType属性设置的,但我想知道可以发送几十种不同类型的消息,并且我希望能够添加它们随着事物的发展相当容易。
虽然代码不会生成错误,但在远端实例化的对象没有任何已发送的数据。我尝试过数据包嗅探,看看我是否可以确认数据实际上在线路上,但我无法理解线路协议。所以我不知道数据在传输中还是在服务器中消失。如果我将代码更改为直接使用TestMessageType实例而不是使用接口,则它可以正常工作。
该解决方案由三个项目组成;一个“类型”程序集,然后引用该程序集的客户端和服务器控制台应用程序。类型程序集包含此代码;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace WCF_TCP_Sandpit
{
public interface ITestInterface
{
Int64 I64Value {get; set;}
}
[ServiceContract]
public interface IServer
{
[OperationContract]
[ServiceKnownType(typeof(TestMessageType))]
ITestInterface Test(ITestInterface msg);
}
[DataContract]
[KnownType(typeof(TestMessageType))]
public class TestMessageType : ITestInterface
{
Int64 _v1;
public long I64Value
{
get { return _v1; }
set { _v1 = value; }
}
public static Type[] KnownTypes()
{
return new Type[] { typeof(TestMessageType) };
}
}
}
服务器代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WCF_TCP_Sandpit;
using System.Runtime.Serialization;
namespace Server
{
class Program : IServer
{
static void Main(string[] args)
{
using (ServiceHost serviceHost = new ServiceHost(typeof(Program), new Uri("net.tcp://127.0.0.1:9000")))
{
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
#region IServer Members
public ITestInterface Test(ITestInterface msg)
{
ITestInterface reply = new TestMessageType();
reply.I64Value = msg.I64Value * 2;
return reply;
}
#endregion
}
}
和客户端的代码是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCF_TCP_Sandpit;
using System.ServiceModel;
namespace Client
{
class Program
{
static void Main(string[] args)
{
ITestInterface m,r;
int i = 0;
ChannelFactory<WCF_TCP_Sandpit.IServer> srv
= new ChannelFactory<WCF_TCP_Sandpit.IServer>
(new NetTcpBinding(), "net.tcp://127.0.0.1:9000");
WCF_TCP_Sandpit.IServer s;
s = srv.CreateChannel();
while (true)
{
m = new WCF_TCP_Sandpit.TestMessageType();
m.I64Value = i++;
r = s.Test(m);
Console.WriteLine("Sent " + m.I64Value + "; received " + r.I64Value);
System.Threading.Thread.Sleep(1000);
}
}
}
}
任何人都可以投在什么地方出了错一些轻?
当你检查数据包(当它工作)它使用XML?我不记得wcf是否会使用xml序列化程序,但它可能会。 (从进一步阅读看来,二进制序列化器使用ootb)。你有没有试过把你的ITestMessage包装成一个'Message'类(即让ITestMessage成为这个Message类的属性) – wal 2012-07-18 15:10:05