Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我在wcf反序列化中获取空数据?_Wcf_Deserialization_Nettcpbinding - Fatal编程技术网

为什么我在wcf反序列化中获取空数据?

为什么我在wcf反序列化中获取空数据?,wcf,deserialization,nettcpbinding,Wcf,Deserialization,Nettcpbinding,我有一个系统,在这个系统中,我在不同的点对点通信通道之间交换消息——在Windows和嵌入式系统之间,并且作为标准的自定义序列化/反序列化函数完成了这一切,几乎完全是手工完成的,因为这使得在Windows端的C和嵌入式系统上的C之间很容易进行移植 现在我想添加一个块,用于在网络上的PC之间进行通信。我决定看看WCF,而不是再做一批相同的工作,使用TcpClient/TcpListener并跟踪重叠的消息和响应 在查看了这里的大量消息和其他地方的文档等之后,我想到了一个非常简单的应用程序,它可以交

我有一个系统,在这个系统中,我在不同的点对点通信通道之间交换消息——在Windows和嵌入式系统之间,并且作为标准的自定义序列化/反序列化函数完成了这一切,几乎完全是手工完成的,因为这使得在Windows端的C和嵌入式系统上的C之间很容易进行移植

现在我想添加一个块,用于在网络上的PC之间进行通信。我决定看看WCF,而不是再做一批相同的工作,使用TcpClient/TcpListener并跟踪重叠的消息和响应

在查看了这里的大量消息和其他地方的文档等之后,我想到了一个非常简单的应用程序,它可以交换消息,服务器包含一个函数,该函数接受并返回一个接口实例,而不是一个固定的类。尽管示例中只有一种消息-因此使用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 
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.ServiceModel;
使用WCF_TCP_沙坑;
使用System.Runtime.Serialization;
命名空间服务器
{  
课程名称:IServer
{
静态void Main(字符串[]参数)
{
使用(ServiceHost ServiceHost=newServiceHost(typeof(Program))和新Uri(“net。tcp://127.0.0.1:9000")))
{
Open();
//现在可以访问该服务。
WriteLine(“服务准备就绪”);
控制台。WriteLine(“按以终止服务”);
Console.WriteLine();
Console.ReadLine();
}
}
#区域IServer成员
公共ITestInterface测试(ITestInterface msg)
{
ITestInterface reply=newtestmessagetype();
reply.I64Value=msg.I64Value*2;
回复;
}
#端区
}
}
客户端代码是

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);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用WCF_TCP_沙坑;
使用System.ServiceModel;
命名空间客户端
{
班级计划
{
静态void Main(字符串[]参数)
{
界面m,r;
int i=0;
通道工厂srv
=新工厂
(新的NetTcpBinding(),“net。tcp://127.0.0.1:9000");
WCF_TCP_Sandpit.IServer s;
s=srv.CreateChannel();
while(true)
{
m=新的WCF_TCP_Sandpit.TestMessageType();
m、 I64Value=i++;
r=s.试验(m);
控制台写入线(“发送”+m.I64Value+“接收”+r.I64Value);
系统线程线程睡眠(1000);
}
}
}
}

有人能解释出哪里出了问题吗?

您的
I64Value
属性不需要
DataMember
属性吗?

当您检查数据包时(当它工作时),它是否使用了xml?我记不起wcf是否会使用现成的xml序列化程序,但它可能会这样做。(从进一步的阅读来看,二进制序列化程序似乎是使用ootb的)。您是否尝试过将ITestMessage包装到
Message
类中(即使ITestMessage成为所述Message类的属性)显然:)很可能我在切换到接口时丢失了它,而不是twitter。它是纯二进制的。我甚至看不到任何特定的值在增加。但是,既然它一开始不是连载的,我就不会了。谢谢你的帮助。