C# Networkcomms.net库发送自定义类

C# Networkcomms.net库发送自定义类,c#,tcp,networkcomms.net,C#,Tcp,Networkcomms.net,几天前,我开始在C#中使用这个。我试图发送自定义类时遇到错误,以下是我的代码: Main.cs private void button3_Click(object sender, EventArgs e) { listBox1.Items.Add("Sending message to server saying '" + textBox2.Text + "'"); TCPConnection connection = TCPConnection

几天前,我开始在C#中使用这个。我试图发送自定义类时遇到错误,以下是我的代码:

Main.cs

    private void button3_Click(object sender, EventArgs e)
    {
        listBox1.Items.Add("Sending message to server saying '" + textBox2.Text + "'");

        TCPConnection connection = TCPConnection.GetConnection(new ConnectionInfo(serverIP, serverPort));
        SendReceiveOptions options = connection.ConnectionDefaultSendReceiveOptions.Clone() as SendReceiveOptions;
        options.DataProcessors.Add(DPSManager.GetDataProcessor<RijndaelPSKEncrypter>());
        RijndaelPSKEncrypter.AddPasswordToOptions(options.Options, "Your strong PSK");

        if (connection.SendReceiveObject<string>("Payload", "Ack", 1000, new PayloadFile(textBox2.Text)) != null) // <-- Giving an exception here, "Type is not expected, and no contract can be inferred: TCP_Client.PayloadFile"
        {
            listBox1.Items.Add("Done");
        }
    }
public class PayloadFile
{
    public string FileName;
    public string FileLocation;
    public FileStream FileContent;

    public PayloadFile(string FileToLoad)
    {
        if (!File.Exists(FileToLoad))
        {
            throw new FileNotFoundException();
        }

        FileInfo PayloadInfo = new FileInfo(FileToLoad);
        FileName = PayloadInfo.Name;
        FileLocation = PayloadInfo.DirectoryName;
        FileContent = File.OpenRead(FileToLoad);
    }
}
与消息一起引发的异常:

Type is not expected, and no contract can be inferred: TCP_Client.PayloadFile

我怀疑这个类写错了?

你需要用ProtoBuffer属性来修饰你的类,让它工作起来。 我使用下面这个取自示例的服务器脚本进行了一些测试。 此外,您不能序列化流对象,您需要使用字节数组

void Main()
{
    //Trigger the method PrintIncomingMessage when a packet of type 'Message' is received
    //We expect the incoming object to be a string which we state explicitly by using <string>
    NetworkComms.AppendGlobalIncomingPacketHandler<PayloadFile>("Payload", PrintIncomingMessage);
    //Start listening for incoming connections
    TCPConnection.StartListening(true);

    //Print out the IPs and ports we are now listening on
    Console.WriteLine("Server listening for TCP connection on:");
    foreach (System.Net.IPEndPoint localEndPoint in TCPConnection.ExistingLocalListenEndPoints()) 
        Console.WriteLine("{0}:{1}", localEndPoint.Address, localEndPoint.Port);

    //Let the user close the server
    Console.WriteLine("\nPress any key to close server.");
    Console.ReadLine();

    //We have used NetworkComms so we should ensure that we correctly call shutdown
    NetworkComms.Shutdown();

}


        /// <summary>
        /// Writes the provided message to the console window
        /// </summary>
        /// <param name="header">The packetheader associated with the incoming message</param>
        /// <param name="connection">The connection used by the incoming message</param>
        /// <param name="message">The message to be printed to the console</param>
        private static void PrintIncomingMessage(PacketHeader header, Connection connection, PayloadFile message)
        {
            connection.SendObject("Ack", "Ok");
            Console.WriteLine("\nA message was recieved from " + connection.ToString() + " which said '" + message + "'.");
        }


// Define other methods and classes here

    [ProtoContract]
    public class PayloadFile
    {
        [ProtoMember(1)]
        public string FileName { get; set; }

        [ProtoMember(2)]
        public string FileLocation { get; set; }

        [ProtoMember(3)]
        public byte[] FileContent { get; set; }

        public PayloadFile()
        {
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.AppendLine(string.Format("FilaName: {0}", FileName));
            sb.AppendLine(string.Format("FileLocation: {0}", FileLocation));
            sb.AppendLine(string.Format("FileContent: {0}", System.Text.Encoding.UTF8.GetString(FileContent)));
            return sb.ToString();
        }

    }
void Main()
{
//当收到“Message”类型的数据包时,触发PrintIncomingMessage方法
//我们希望传入对象是一个字符串,我们使用
NetworkComms.AppendGlobalIncomingPacketHandler(“有效载荷”,PrintIncomingMessage);
//开始侦听传入的连接
TCPConnection.StartListening(真);
//打印出我们正在监听的IP和端口
WriteLine(“服务器正在侦听:”)上的TCP连接;
foreach(TCPConnection.ExistingLocalListenEndPoints()中的System.Net.IPEndPoint localEndPoint)
WriteLine(“{0}:{1}”,localEndPoint.Address,localEndPoint.Port);
//让用户关闭服务器
Console.WriteLine(“\n按任意键关闭服务器”);
Console.ReadLine();
//我们使用了NetworkComms,因此我们应该确保正确调用shutdown
NetworkComms.Shutdown();
}
/// 
///将提供的消息写入控制台窗口
/// 
///与传入消息关联的packetheader
///传入消息使用的连接
///要打印到控制台的消息
私有静态void printincingmessage(PacketHeader头、连接、PayloadFile消息)
{
SendObject(“确认”、“确定”);
Console.WriteLine(“\n从“+connection.ToString()+”接收到一条消息,该消息表示“+message+””);
}
//在此处定义其他方法和类
[原始合同]
公共类付费文件
{
[原成员(1)]
公共字符串文件名{get;set;}
[原成员(2)]
公共字符串文件位置{get;set;}
[原成员(3)]
公共字节[]文件内容{get;set;}
公共PayloadFile()
{
}
公共重写字符串ToString()
{
var sb=新的StringBuilder();
AppendLine(string.Format(“FilaName:{0}”,文件名));
AppendLine(string.Format(“FileLocation:{0}”,FileLocation));
AppendLine(string.Format(“FileContent:{0}”,System.Text.Encoding.UTF8.GetString(FileContent));
使某人返回字符串();
}
}
这是客户端的脚本

void Main()
{
    var serverIP = "::1";
    var serverPort = 10000;

    TCPConnection connection = TCPConnection.GetConnection(new ConnectionInfo(serverIP, serverPort));
    SendReceiveOptions options = connection.ConnectionDefaultSendReceiveOptions.Clone() as SendReceiveOptions;
    options.DataProcessors.Add(DPSManager.GetDataProcessor<RijndaelPSKEncrypter>());
    RijndaelPSKEncrypter.AddPasswordToOptions(options.Options, "Your strong PSK");

    if (connection.SendReceiveObject<string>("Payload", "Ack", 1000, 
        new PayloadFile("c:\\CONFIGURACAO.INI")) != null) 
    {
        Console.WriteLine("Done");
    }

}

[ProtoContract]
public class PayloadFile
{
    [ProtoMember(1)]
    public string FileName { get; set; }

    [ProtoMember(2)]
    public string FileLocation { get; set; }

    [ProtoMember(3)]
    public byte[] FileContent { get; set; }

    public PayloadFile()
    {
    }

    public PayloadFile(string FileToLoad)
    {
        if (!File.Exists(FileToLoad))
        {
            throw new FileNotFoundException();
        }
        FileInfo PayloadInfo = new FileInfo(FileToLoad);
        FileName = PayloadInfo.Name;
        FileLocation = PayloadInfo.DirectoryName;
        using (var stream = File.OpenRead(FileToLoad))
        {
            FileContent = unchecked((new BinaryReader(stream)).ReadBytes((int)stream.Length));
        }
    }

}
void Main()
{
var serverIP=“::1”;
var serverPort=10000;
TCPConnection connection=TCPConnection.GetConnection(新连接信息(serverIP,serverPort));
SendReceiveOptions=connection.ConnectionDefaultSendReceiveOptions.Clone()作为SendReceiveOptions;
options.DataProcessors.Add(DPSManager.GetDataProcessor());
RijndaelpskeEncrypter.AddPasswordToOptions(options.options,“您的强PSK”);
if(connection.SendReceiveObject(“有效载荷”,“确认”),1000,
新的加载文件(“c:\\CONFIGURACAO.INI”)!=null)
{
控制台。写入线(“完成”);
}
}
[原始合同]
公共类付费文件
{
[原成员(1)]
公共字符串文件名{get;set;}
[原成员(2)]
公共字符串文件位置{get;set;}
[原成员(3)]
公共字节[]文件内容{get;set;}
公共PayloadFile()
{
}
公共PayloadFile(字符串FileToLoad)
{
如果(!File.Exists(FileToLoad))
{
抛出新的FileNotFoundException();
}
FileInfo PayloadInfo=新文件信息(FileToLoad);
FileName=PayloadInfo.Name;
FileLocation=PayloadInfo.DirectoryName;
使用(var stream=File.OpenRead(FileToLoad))
{
FileContent=unchecked((新二进制读取器(流)).ReadBytes((int)stream.Length));
}
}
}

错误消息来自protobuf net,该库使用protobuf net作为默认序列化程序。演示如何创建使用protobuf net的类。另见感谢@dtb。。。你能提供一些我可以遵循的例子吗?谢谢你看过上面链接中的例子了吗?是的,但仍然不知道如何实现……你在哪一点上被卡住了?在堆栈溢出上有一些错误。也许其中一个有用?