Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# protobuf网与重复场_C#_Java_Protocol Buffers_Protobuf Net - Fatal编程技术网

C# protobuf网与重复场

C# protobuf网与重复场,c#,java,protocol-buffers,protobuf-net,C#,Java,Protocol Buffers,Protobuf Net,在protobuf中使用列表作为重复字段的对应项是否正确?我正在尝试这个,但总是出现异常: 导线类型无效;这通常意味着您在没有截断或设置长度的情况下重写了文件;看 整个缓冲区是(第一个消息,下一个到达的消息附加到此消息): 985262423898321 java protobuf文件: package XXX; option java_package = "XXX"; option java_outer_classname = "Protos"; option optimize_for =

在protobuf中使用列表作为重复字段的对应项是否正确?我正在尝试这个,但总是出现异常:

导线类型无效;这通常意味着您在没有截断或设置长度的情况下重写了文件;看

整个缓冲区是(第一个消息,下一个到达的消息附加到此消息): 985262423898321

java protobuf文件:

package XXX;

option java_package = "XXX";
option java_outer_classname = "Protos";

option optimize_for = SPEED;

message V3DDelta {
  optional int32 bid = 1;
  optional int32 bidSize = 2;
  optional int32 ask = 3;
  optional int32 askSize = 4;
}

message Request {
  optional int32 type = 1;
  optional string request = 2;
}

message Response {
  optional int32 type = 1;
  optional string response = 2;
  repeated V3DDelta v3dDelta = 3;
}
和protbuf网络类:

[ProtoContract]
public class V3DDelta {
    [ProtoMember(1)]
    public double bid { get; set; }
    [ProtoMember(2)]
    public int bidSize { get; set; }
    [ProtoMember(3)]
    public double ask { get; set; }
    [ProtoMember(4)]
    public int askSize { get; set; }
}

[ProtoContract]
public class Request {
    [ProtoMember(1)]
    public int Type { get; set; }
    [ProtoMember(2)]
    public string Rq { get; set; }
}

[ProtoContract]
public class Response {
    [ProtoMember(1)]
    public int Type { get; set; }
    [ProtoMember(2)]
    public string Rsp { get; set; }
    [ProtoMember(3)]
    public List<V3DDelta> v3dDelta { get; set; }
    public Response() {
        v3dDelta = new List<V3DDelta>();
    }
}
[协议]
公共类V3DDelta{
[原成员(1)]
公共双标{get;set;}
[原成员(2)]
公共整数bidSize{get;set;}
[原成员(3)]
公共双询问{get;set;}
[原成员(4)]
public int askSize{get;set;}
}
[原始合同]
公共类请求{
[原成员(1)]
公共int类型{get;set;}
[原成员(2)]
公共字符串Rq{get;set;}
}
[原始合同]
公众课堂反应{
[原成员(1)]
公共int类型{get;set;}
[原成员(2)]
公共字符串Rsp{get;set;}
[原成员(3)]
公共列表v3dDelta{get;set;}
公众回应({
v3dDelta=新列表();
}
}
我尝试了V3DDelta[],但结果是一样的。 阅读信息:

Response rsp = Serializer.DeserializeWithLengthPrefix<Response>(rcvstream, PrefixStyle.Base128);
Response rsp=Serializer.DeserializeWithLengthPrefix(rcvstream,PrefixStyle.Base128);
在java中,消息是使用writeDelimitedTo发送的。 c#中的缓冲区与java中的完全相同。 当有一个v3dDelta字段时,一切都按预期工作。

是的,
列表
或数组(
T[]
)将用于
重复
。顺便提一下,有一个工具可以从.proto定义生成protobuf网络类

您试图“使用长度前缀”读取它,但是:9作为变量前缀无效(
9
,作为字段标题,意味着“字段1,固定64位数据”,但是:在此上下文中,它应该是变量)

实际上,none数据与
9
作为字段头是兼容的,因为在字段
1
的定义中没有任何64位值。您确实有一个
double
作为字段
3
,这将很好地完成这项工作-但是,这将是
73
作为字段标题

我会告诉你序列9,8,5,。。。然而,代表-我们将:

9 : field 1, fixed 64-bit
    8 5 26 5 24 238 98 32 <== payload for above
1 : field 0, fixed 64-bit
    ^^ not *really* valid, but fields <= 0 generally mean "stop" - but
       frankly this is not a clean/defined/expected exit condition
这给了我们
9
,我们还有
9
字节,所以看起来不错

8 : Field 1, varint
  5 = payload of above
26 : Field 3, length-delimited
  5 = length of payload
   24 238 98 32 1 = payload of ^^^
      24 : Field 3, varint
          238, 98 = payload of ^^^ = 12654
      32 : Field 4, varint
          1 = payload of ^^^ = 1
现在看起来它应该解析。。。调查为什么不是


编辑2:经过一点调试后,部分原因是您(很抱歉)损坏了
v3ddeta
属性。您在proto中将它们定义为
int32
(字段3是数据中的变量),但您将它们实现为
double
。。。和
double
int32
不是朋友

因此:

然后,以下方法可以很好地工作:

using (var ms = new MemoryStream(buffer))
{
    int len = ProtoReader.DirectReadVarintInt32(ms);
    var resp = (Response)model.Deserialize(ms, null, typeof(Response), len);

    Assert.AreEqual(5, resp.Type);
    Assert.AreEqual(1, resp.v3dDelta.Count);
    Assert.AreEqual(12654, resp.v3dDelta[0].ask);
    Assert.AreEqual(1, resp.v3dDelta[0].askSize);
}
从技术上讲,我可以让protobuf net接受一个
varint
值作为
double
值,但这高度表明模式并不真正匹配,因此我认为正确的做法是在这种情况下更改类型。

是的,
List
或数组(
t[]
)将适用于
重复的
。顺便提一下,有一个工具可以从.proto定义生成protobuf网络类

您试图“使用长度前缀”读取它,但是:9作为变量前缀无效(
9
,作为字段标题,意味着“字段1,固定64位数据”,但是:在此上下文中,它应该是变量)

实际上,none数据与
9
作为字段头是兼容的,因为在字段
1
的定义中没有任何64位值。您确实有一个
double
作为字段
3
,这将很好地完成这项工作-但是,这将是
73
作为字段标题

我会告诉你序列9,8,5,。。。然而,代表-我们将:

9 : field 1, fixed 64-bit
    8 5 26 5 24 238 98 32 <== payload for above
1 : field 0, fixed 64-bit
    ^^ not *really* valid, but fields <= 0 generally mean "stop" - but
       frankly this is not a clean/defined/expected exit condition
这给了我们
9
,我们还有
9
字节,所以看起来不错

8 : Field 1, varint
  5 = payload of above
26 : Field 3, length-delimited
  5 = length of payload
   24 238 98 32 1 = payload of ^^^
      24 : Field 3, varint
          238, 98 = payload of ^^^ = 12654
      32 : Field 4, varint
          1 = payload of ^^^ = 1
现在看起来它应该解析。。。调查为什么不是


编辑2:经过一点调试后,部分原因是您(很抱歉)损坏了
v3ddeta
属性。您在proto中将它们定义为
int32
(字段3是数据中的变量),但您将它们实现为
double
。。。和
double
int32
不是朋友

因此:

然后,以下方法可以很好地工作:

using (var ms = new MemoryStream(buffer))
{
    int len = ProtoReader.DirectReadVarintInt32(ms);
    var resp = (Response)model.Deserialize(ms, null, typeof(Response), len);

    Assert.AreEqual(5, resp.Type);
    Assert.AreEqual(1, resp.v3dDelta.Count);
    Assert.AreEqual(12654, resp.v3dDelta[0].ask);
    Assert.AreEqual(1, resp.v3dDelta[0].askSize);
}

从技术上讲,我可以让protobuf net接受一个
varint
值作为
double
值,但这高度表明一个模式并不真正匹配,因此我认为正确的做法是在这种情况下更改类型。

一切正常。。。真有趣!一切正常。。。真有趣!是的,就是它,现在它正常工作了。我只是忘记了在proto中更改字段类型之后更改字段类型。谢谢你,很抱歉耽误了你的时间。是的,就是这样,现在它正常工作了。我只是忘记了在proto中更改字段类型之后更改字段类型。谢谢你,很抱歉耽误了你的时间。