java - 套接字 InputStream 和 UTF-8

标签 java sockets encoding utf-8

我正在尝试与 Java 聊天。一切正常,除了特殊字符不起作用。我认为这是一个编码问题,因为在我的 Outputstream 中我用 UTF-8 编码字符串,如下所示:

  protected void send(String msg) {
    
        try {
          msg+="\r\n";            
          OutputStream outStream = socket.getOutputStream();              
          outStream.write(msg.getBytes("UTF-8"));
          System.out.println(msg.getBytes("UTF-8"));
          outStream.flush();
        }
        catch(IOException ex) {
          ex.printStackTrace();
        }
      }
但在我的 receive方法我没有找到这样做的方法:
public String receive() throws IOException {
   
    String line = "";
    InputStream inStream = socket.getInputStream();    
                
    int read = inStream.read();
    while (read!=10 && read > -1) {
      line+=String.valueOf((char)read);
      read = inStream.read();
    }
    if (read==-1) return null;
    line+=String.valueOf((char)read);       
    return line; 
    
  }
那么有没有一种快速的方法来指定缓冲区读取的字节是用 UTF-8 编码的?
编辑:好的,我尝试使用 BufferedReader像这样:
 public String receive() throws IOException {
    
    String line = "";           
    in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));           
    String readLine = "";   
    
    while ((readLine = in.readLine()) != null) {
        line+=readLine;
    }
    
    System.out.println("Line:"+line);
    
    return line;
   
  }
但它不起作用。似乎套接字没有收到任何东西。

最佳答案

试图为 future 的访客提供更多的光线。

经验法则: 服务器和客户端必须在编码方案之间同步,因为如果客户端发送使用某种编码方案编码的数据而服务器正在使用其他编码方案读取数据,则永远无法实现预期的结果。

需要注意的重要事项 对于尝试测试这一点的人来说,不要在客户端以 ASCII 编码(或换句话说在客户端使用 ASCII 编码)并在服务器端使用 UTF8 解码(或换句话说使用 UTF8在服务器端编码)因为 UTF8 向后兼容 ASCII,所以可能会觉得“经验法则”是错误的,但不,它不是,所以最好在客户端使用 UTF8,在服务器端使用 UTF16,你就会明白。

使用套接字编码

我想要理解的最重要的事情是: 最后通过您要发送的套接字 BYTES 但这一切都取决于这些字节的编码方式

例如,如果我使用 Windows 命令提示符将输入发送到服务器(通过客户端 - 服务器套接字),那么数据将使用某种编码方案进行编码(我真的不知道是哪个),如果我使用另一个客户端将数据发送到服务器代码/程序然后我可以指定我想用于我的客户端套接字的 o/p 流的编码方案,然后所有数据将使用该编码方案转换/编码为 BYTES 并通过套接字发送。

现在,最后我仍然通过线路发送 BYTES,但这些是使用我指定的编码方案进行编码的。如果 假设在服务器端,我在读取套接字的 i/p 流时使用另一种编码方案,则无法达到预期的结果,如果我在服务器上使用相同的编码方案(与客户端的编码方案相同),那么一切都会是完美的

回答这个问题

在 Java 中,有特殊的“桥接”流(读取 here )可用于指定流的编码。

请注意:Java 中的 InputStreamOutputStream 是 BYTE 流,因此使用这些流读取和写入的所有内容都将是 BYTES,您不能使用 0x10455667104 类和 Java67x914 类的对象指定编码,因此可以使用桥接类。

下面是客户端和服务器的代码片段,我试图向 展示如何在客户端的输出流和服务器的输入流 上指定编码。

只要我在两端指定相同的编码,一切都会很完美。

客户端:

        Socket clientSocket = new Socket("abc.com", 25050);
        OutputStreamWriter clientSocketWriter = (new OutputStreamWriter(clientSocket.getOutputStream(), "UTF8"));

服务器端:
    ServerSocket serverSocket = new ServerSocket(8001);
    Socket clientSocket = serverSocket.accept();
    // PLEASE NOTE: important thing below is I am specifying the encoding over my socket's input stream, and since Java's <<InputStream>> is a BYTE stream,  
    // so in order to specify the encoding I am using Java I/O's bridge class <<InputStreamReader>> and specifying my UTF8 encoding.
    // So, with this all my data (BYTES really) will be read from client socket as bytes "BUT" those will be read as UTF8 encoded bytes.
    // Suppose if I specify different encoding here, than what client is specifying in its o/p stream than data cannot read properly and may be all "?"
    InputStreamReader clientSocketReader = (new InputStreamReader(clientSocket.getInputStream(), "UTF8"));

关于java - 套接字 InputStream 和 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24393112/

相关文章:

php - 字符串编码/解码(PHP-Android)

java - 来自在线测试站点的代码编码

c# - 是否有任何适用于 ASP.NET MVC 应用程序的开源 Comet Web 服务器?

python - 套接字接收不返回

linux - 同一台计算机上的套接字客户端和服务器可以绑定(bind)到同一端口吗?

c++ - Windows 游戏 : UTF-8, UTF-16、DirectX 和 Lua

java - 禁用整个 JPanel 包括其内部的组件

java - 如果()不工作

javax.persistence.RollbackException : Error while committing the transaction in JPA code

windows - "Error 1722"尝试将 JDK 安装到非默认位置