0

我有一个系统,我在不同的点对点通信通道之间交换消息 - 在 Windows 和嵌入式系统之间,并且已经完成了这一切作为非常标准的自定义序列化/反序列化功能几乎完全手动完成,因为这很容易在 Windows 端的 C# 和嵌入式的 C 之间移植。

现在我想添加一个在整个网络上的 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);
            }
        }
    }
}

任何人都可以对出了什么问题有所了解吗?

4

1 回答 1

0

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

于 2012-07-18T15:18:50.073 回答