Python 到 C# 的套接字消息传输出现乱码问题

3

我将尝试使用simplejson和Json.NET在Python服务器和C#客户端之间建立基本的ZeroMQ套接字链接。我尝试从Python发送一个字典,并在C#中将其读入一个对象。

message = {'MessageType':"None", 'ContentType':"None", 'Content':"OK"}
message_blob = simplejson.dumps(message).encode(encoding = "UTF-8")
alive_socket.send(message_blob)

这条信息被作为普通的UTF-8字符串发送,或者如果我使用UTF-16,则会发送为“'\xff\xfe{\x00”\x00...”等等。

C#代码是我的问题所在:

string reply = client.Receive(Encoding.UTF8);

收到的UTF-8消息是“≻潃瑮湥≴›…”等。

我尝试使用UTF-16,消息可以正常传输,但第一个符号仍然是小端的 \xFF \xFE BOM,所以当我尝试将其提供给反序列化程序时,会出现问题。

PythonMessage replyMessage = JsonConvert.DeserializeObject<PythonMessage>(reply);
//PythonMessage is just a very simple class with properties,
//not relevant to the problem

我遇到了一个错误 (显然是在第一个符号 \xFF处引起的):
Unexpected character encountered while parsing value: .

我在使用编码方面显然出现了问题。你能否向我展示正确的做法?


你尝试发送一个简单的字符串而不是字典了吗?那样行得通吗? - raffian
如果我像编码dumps()的结果那样编码一个字符串,那么它也是一样的。 - Alex Bausk
这个 Receive 方法是什么?难道 Socket.Receive 只接受字节数组吗?那么 client 是什么? - Joni
这是使用ZeroMQ接收套接字字符串的客户端方法。使用以下代码定义:using (ZmqContext context = ZmqContext.Create()) using (ZmqSocket client = context.CreateSocket(SocketType.REQ)) - Alex Bausk
1个回答

1
字节顺序标记在UTF-16中是强制的。您可以使用UTF-16LE或UTF-16BE来假定特定的字节顺序,这样就不会生成BOM。也就是说,使用:
message_blob = simplejson.dumps(message).encode(encoding = "UTF-16le")

我认为 FFFE 是小端序 BOM,你觉得呢? - Alex Bausk
我猜问题是,如何让DeserializeObject正确地消耗UTF-16字符串?我应该将其转换为UTF-8(如果是的话,如何转换?)还是只需丢弃前两个字节?后者对我来说绝对是错误的。谢谢! - Alex Bausk
1
@AlexBausk,看起来问题出在zeromq客户端如何解码字符串上:它没有删除字节顺序标记。你要么自己删除它,要么一开始就不生成它(参见编辑)。再说了,使用UTF-8编码可以避免整个BOM混乱的麻烦。从源代码(https://github.com/zeromq/clrzmq/blob/master/src/ZeroMQ/SendReceiveExtensions.cs)来看,我没有看到为什么ZeroMQ客户端应该忽略你传递的编码,你确定你测试时运行的是最新版本的C#代码吗? - Joni
我在 Stack Overflow 上找到了一个类似的问题,人们只需使用 .Remove() 去除字节顺序标记。是的,现在它可以工作了,谢谢!但我仍然不知道为什么 UTF-8 会出现乱码。你能否推荐一些关于在 C# 中处理/转换编码的好读物或示例?我对 C# 几乎没有任何经验。 - Alex Bausk
谢谢!现在我有UTF-16 -> UTF-16的传输,至少我能做到这么多。 - Alex Bausk
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接