【问题标题】:Failing to send protobuf stream over a named pipe and getting result back无法通过命名管道发送 protobuf 流并返回结果
【发布时间】:2019-04-10 15:46:25
【问题描述】:

我在使用命名管道来回发送对象(双工通信)时遇到问题。代码:

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 无济于事。是否可以在双工通信中传输protobuf 对象?如果有人能指出我做错了什么,我将不胜感激。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多