2

几天前,我开始在 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");
        }
    }

PayloadFile.cs

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

我怀疑这门课写错了?

4

1 回答 1

3

您需要使用 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()
{
    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));
        }
    }

}
于 2013-09-23T14:28:09.273 回答