【发布时间】:2020-11-03 19:25:57
【问题描述】:
我正在编写一个使用协议缓冲区对一些数据进行编码的小型服务器。
-
Android Client 和 Python Server 之间打开 TCP Socket
-
Android 客户端发送字符串以作为普通换行符分隔的 utf-8 进行处理。
-
Python Server 进行一些处理以生成响应,该响应给出一个 Int 数组数组:[[int]]。这是在协议缓冲区文件中编码的:
syntax = "proto2";
package tts;
message SentenceContainer {
repeated Sentence sentence = 1;
}
message Sentence {
repeated uint32 phonemeSymbol = 1;
}
它被加载到这个结构中并按如下方式发送......
container = ttsSentences_pb2.SentenceContainer()
for sentence in input_sentences:
phonemes = container.sentence.add()
# Add all the phonemes to the phoneme list
phonemes.phonemeSymbol.extend(processor.text_to_sequence(sentence))
payload = container.SerializeToString()
client.send(payload)
- Android 客户端收到 Protocol Buffer 编码的消息并尝试解码。
这就是我被困的地方......
# I get the InputStream when the TCP connection is first opened
bufferIn = socket.getInputStream();
TtsSentences.SentenceContainer sentences = TtsSentences.SentenceContainer.parseDelimitedFrom(bufferIn);
当客户端收到消息时会出现这个异常:
E/TCP: Server Error
com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag.
at com.google.protobuf.CodedInputStream.checkLastTagWas(CodedInputStream.java:164)
at com.google.protobuf.GeneratedMessageLite.parsePartialDelimitedFrom(GeneratedMessageLite.java:1527)
at com.google.protobuf.GeneratedMessageLite.parseDelimitedFrom(GeneratedMessageLite.java:1496)
at com.tensorspeech.tensorflowtts.TtsSentences$SentenceContainer.parseDelimitedFrom(TtsSentences.java:221)
at com.tensorspeech.tensorflowtts.network.PersistentTcpClient.run(PersistentTcpClient.java:100)
at com.tensorspeech.tensorflowtts.MainActivity.lambda$onCreate$0$MainActivity(MainActivity.java:71)
at com.tensorspeech.tensorflowtts.-$$Lambda$MainActivity$NTUE8bAusaoF3UGkWb7-Jt806BY.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:919)
我已经知道这个问题是因为协议缓冲区不是自定界的,但我不确定我应该如何正确定界。我已尝试添加换行符client.send(payload + b'\n'),并将 PB 大小(以字节为单位)添加到负载 client.send(container.ByteSize().to_bytes(2, 'little') + payload) 的开头,但不知道如何继续。
很遗憾没有关于如何在 Java 中通过 TCP 套接字使用协议缓冲区的文档...
【问题讨论】:
-
您似乎只发送了一条消息。为什么使用
parseDelimitedFrom而不是parseFrom?但更重要的是,问题看起来像如何从 Python 中分隔,而不是如何从 Java 中解析。 -
谢谢。我认为问题出在双方,首先我需要知道如何从 Python 中分隔,然后还要知道我需要在 Java 上使用哪些缓冲区/输入类型才能正确解析该分隔符。
-
您只发送一条消息吗?如果是这样,那么您根本不必分隔。
-
是的,但由于某种原因,它只是无限期地阻止
parseFrom(bufferIn)。 -
发送一条消息后连接是否关闭?
标签: java python protocol-buffers