我在使用命名管道来回传输对象(双工通信)时遇到了麻烦。代码:
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
方法似乎永远不会停止从流中读取数据,因此我永远无法解码编码服务器请求。但是如果强制停止客户端,则会收到请求。
我也尝试使用SteamWriter
和StreamReader
无济于事。是否有可能在双工通信中传输protobuf对象?如果有人能指出我做错了什么,我将不胜感激。
protobuf不是一种自终止数据格式;你需要使用某种框架。幸运的是,该库包含一些基本实现以方便您使用,因此:如果您使用SerializeWithLengthPrefix
和DeserializeWithLengthPrefix
(确保在两侧使用相同的配置):它应该可以工作。
没有框架:protobuf的性质是“读到流的末尾”,即你正在看到的。这样做的原因是,即使对于单个消息,protobuf也是可以连接的(这是一个单词吗?)。