在Ruby中,如何从套接字读取UTF-8?

lca*_*ter 5 ruby sockets utf-8

当服务器发送UTF-8字节时,如何在没有字符成为纯字节的情况下读取它们?(\ x40等)

Way*_*rad 5

您可以使用IO#set_encoding将套接字的外部编码设置为 UTF-8。

\n\n
#!/usr/bin/env ruby\n# -*- coding: utf-8 -*-\n\nrequire \'socket\'\n\nserver_socket = TCPServer.new(\'localhost\', 0)\nThread.new do\n  loop do\n    session_socket = server_socket.accept\n    session_socket.set_encoding \'ASCII-8BIT\'  \n    session_socket.puts "\xe1\x9a\x80 \xe1\x9a\x81 \xe1\x9a\x82 \xe1\x9a\x83 \xe1\x9a\x84 \xe1\x9a\x85 \xe1\x9a\x86 \xe1\x9a\x87 \xe1\x9a\x88 \xe1\x9a\x89 \xe1\x9a\x8a \xe1\x9a\x8b \xe1\x9a\x8c \xe1\x9a\x8d"\n    session_socket.close\n  end\nend\n\nclient_socket = TCPSocket.new(\'localhost\', server_socket.addr[1])\nclient_socket.set_encoding \'UTF-8\'\np client_socket.gets\n# => "|\xe1\x9a\x80 \xe1\x9a\x81 \xe1\x9a\x82 \xe1\x9a\x83 \xe1\x9a\x84 \xe1\x9a\x85 \xe1\x9a\x86 \xe1\x9a\x87 \xe1\x9a\x88 \xe1\x9a\x89 \xe1\x9a\x8a \xe1\x9a\x8b \xe1\x9a\x8c \xe1\x9a\x8d\\n"\n
Run Code Online (Sandbox Code Playgroud)\n


Mla*_*vić 4

我相信read_nonblock使用read,它反过来说:

结果字符串始终是 ASCII-8BIT 编码。

这意味着您不需要指定IO#set_encoding,但您可以在读取整个字符串后,强制其编码(使用String#force_encoding!)为UTF-8

我强调了“整体”,因为您需要确保在字符串末尾读取整个 Unicode 字符,就好像只读取了其中的一部分一样,您将得到无效的 UTF-8 字符,并且 Ruby 可能会进一步抱怨它线。