C# SSH.NET 半双工原始二进制连接
C# SSH.NET half-duplex raw binary connection
我正在尝试在 C#/.NET 5 中使用 SSH.NET 获得半双工 ssh 连接,以发送 protobuf 格式的数据包。 (虽然全双工会很好,但我可以使用两个流来模拟)
到目前为止,我能够来回获取数据,但有一些注意事项:
- 我需要发送换行符才能实际提交任何信息。
- 我只能发送纯文本,发送 protobuf 格式的二进制数据会产生奇怪的反序列化错误,可能与编码错误有关。
目前我正在尝试在客户端使用 SSH.NETs ShellStream 并使用 ProtoBufs 非通用反序列化器进行反序列化,将类型映射到带有字典的索引:
using SshClient client = new(connectionInfo);
var stream = client.CreateShellStream("", 80, 24, 800, 600, 1024, new Dictionary<TerminalModes, uint>());
stream.WriteLine("./bin/myProcess");
stream.Expect("Running");
// The stream is now at the point where the packets are supposed to be sent
// Two dicts for mapping types to indicies and back
// Just send strings as packets for now
Dictionary<int, Type> typeByIndex = new { [0] = typeof(string) };
Dictionary<Type, int> indexByType = new { [typeof(string)] = 0 };
// Send a packet over
Serializer.SerializeWithLengthPrefix(
stream, "Hello World!",
PrefixStyle.Base128, indexByType[typeof(string)]);
stream.WriteLine(""); // Write newline to commit and use SSH.NET writing method to directly flush
while (true)
{
if (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
stream, PrefixStyle.Base128,
field => typeByIndex[field-1], out var packet)) Console.WriteLine(packet);
}
服务器 (./bin/myProcess
) 仅使用相同的 while 循环从 Console.OpenStandardInput()
中读取数据。
这会产生反序列化错误(Unexpected wire-type
通常)。我的猜测是这与编码问题有关。
考虑到 SSH.NET 的文档不是很好,我真的不知道在这里尝试什么。
总结一下:
我将如何配置 SSH.NET 以允许来回发送任意 protobuf 格式的二进制数据(没有任何类型的编码转换或控制字符导致问题)以及我将如何绕过必须发送每个数据包的换行符?
它听起来就像它在此处为您提供的 Stream 实际上是基于文本的控制台的包装器,并不真正支持任意二进制文件。这是你可能应该问包创建者的东西 - 可能有一些切换来启用“二进制模式”或类似的,但没有那个 - 老实说我有点惊讶它没有给你 text-writer/text-reader API 而不是流。
最坏的情况,您可以对 protobuf 数据进行 base-64 编码,然后将其发送到文本协议,然后在另一端将其反转。
我正在尝试在 C#/.NET 5 中使用 SSH.NET 获得半双工 ssh 连接,以发送 protobuf 格式的数据包。 (虽然全双工会很好,但我可以使用两个流来模拟)
到目前为止,我能够来回获取数据,但有一些注意事项:
- 我需要发送换行符才能实际提交任何信息。
- 我只能发送纯文本,发送 protobuf 格式的二进制数据会产生奇怪的反序列化错误,可能与编码错误有关。
目前我正在尝试在客户端使用 SSH.NETs ShellStream 并使用 ProtoBufs 非通用反序列化器进行反序列化,将类型映射到带有字典的索引:
using SshClient client = new(connectionInfo);
var stream = client.CreateShellStream("", 80, 24, 800, 600, 1024, new Dictionary<TerminalModes, uint>());
stream.WriteLine("./bin/myProcess");
stream.Expect("Running");
// The stream is now at the point where the packets are supposed to be sent
// Two dicts for mapping types to indicies and back
// Just send strings as packets for now
Dictionary<int, Type> typeByIndex = new { [0] = typeof(string) };
Dictionary<Type, int> indexByType = new { [typeof(string)] = 0 };
// Send a packet over
Serializer.SerializeWithLengthPrefix(
stream, "Hello World!",
PrefixStyle.Base128, indexByType[typeof(string)]);
stream.WriteLine(""); // Write newline to commit and use SSH.NET writing method to directly flush
while (true)
{
if (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
stream, PrefixStyle.Base128,
field => typeByIndex[field-1], out var packet)) Console.WriteLine(packet);
}
服务器 (./bin/myProcess
) 仅使用相同的 while 循环从 Console.OpenStandardInput()
中读取数据。
这会产生反序列化错误(Unexpected wire-type
通常)。我的猜测是这与编码问题有关。
考虑到 SSH.NET 的文档不是很好,我真的不知道在这里尝试什么。
总结一下: 我将如何配置 SSH.NET 以允许来回发送任意 protobuf 格式的二进制数据(没有任何类型的编码转换或控制字符导致问题)以及我将如何绕过必须发送每个数据包的换行符?
它听起来就像它在此处为您提供的 Stream 实际上是基于文本的控制台的包装器,并不真正支持任意二进制文件。这是你可能应该问包创建者的东西 - 可能有一些切换来启用“二进制模式”或类似的,但没有那个 - 老实说我有点惊讶它没有给你 text-writer/text-reader API 而不是流。
最坏的情况,您可以对 protobuf 数据进行 base-64 编码,然后将其发送到文本协议,然后在另一端将其反转。