无法通过命名管道发送protobuf流并无法返回结果

时间:2019-04-10 15:46:26

标签: c# .net-core named-pipes protobuf-net

我无法使用命名管道来回发送对象(双工通信)。代码:

Dto:

[ProtoContract]
public class ServerResponse
{
    [ProtoMember(1)]
    public string FirstName { get; set; }

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

[ProtoContract]
public class ServerRequest
{
    [ProtoMember(1)]
    public string Name { get; set; }

    [ProtoMember(2)]
    public int Age { get; set; }
}

服务器:

static void Main(string[] args)
{
    Console.WriteLine("Starting Server");
    StartServer();
    Console.WriteLine("Press any key to stop server..");
    Console.ReadKey();
}

static void StartServer()
{
    Task.Factory.StartNew(() =>
    {
        var server = new NamedPipeServerStream("MyPipes");

        server.WaitForConnection();
        Console.WriteLine("Connected");

        //StreamReader reader = new StreamReader(server);
        //StreamWriter writer = new StreamWriter(server);
        while (true)
        {
            //string line = reader.ReadLine();
            //Console.WriteLine(line);
            //writer.WriteLine(line.ToUpper());
            //writer.Flush();

            var request = Serializer.Deserialize<ServerRequest>(server);
            Console.WriteLine($"Name: {request.Name}, Age: {request.Age}");

            var response = new ServerResponse() { FirstName = request.Name, LastName = "Always this name!" };
            Serializer.Serialize(server, response);
            server.Flush();
        }
    });
}

客户:

static void Main(string[] args)
{
    Console.WriteLine("Client");

    var client = new NamedPipeClientStream("MyPipes");
    client.Connect();

    //StreamReader reader = new StreamReader(client);
    //StreamWriter writer = new StreamWriter(client);
    while (true)
    {
        //string input = Console.ReadLine();
        //if (String.IsNullOrEmpty(input)) break;
        //writer.WriteLine(input);
        //writer.Flush();
        //Console.WriteLine(reader.ReadLine());

        string firstName = Console.ReadLine();
        var request = new ServerRequest() { Name = firstName, Age = firstName.Length };
        Serializer.Serialize(client, request);
        client.Flush();

        var response = Serializer.Deserialize<ServerResponse>(client);
        Console.WriteLine($"Name: {response.FirstName}, Age: {response.LastName}");
    }

    Console.WriteLine("Done");
    Console.ReadKey();
}

当发送一行string时,效果很好,但是protobuf对我失败。

由于某种原因,Deserialize方法似乎永远不会停止从流中读取数据,因此我永远无法解码编码服务器请求。但是,如果客户端被强制停止,则请求将被接收。

我也尝试使用SteamWriterStreamReader无济于事。是否可以在双工通信中传输probubuf对象?如果有人指出我做错了,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

protobuf不是自终止数据格式;您需要使用某种框架。幸运的是,为方便起见,该库包含一些基本的实现,因此:如果您使用SerializeWithLengthPrefixDeserializeWithLengthPrefix(确保双方都使用相同的配置):它应该可以工作。

没有框架:protobuf的本质是“读到流的末尾”,即您所看到的正好。原因是protobuf被设计为可连接的(是一个单词吗?)即使是单个消息