Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
Java 套接字输入流和UTF-8_Java_Sockets_Encoding_Utf 8 - Fatal编程技术网

Java 套接字输入流和UTF-8

Java 套接字输入流和UTF-8,java,sockets,encoding,utf-8,Java,Sockets,Encoding,Utf 8,我正在尝试与Java聊天。一切都很好,除了特殊角色不起作用。我认为这是一个编码问题,因为在我的Outputstream中,我将字符串编码为UTF-8,如下所示: protected void send(String msg) { try { msg+="\r\n"; OutputStream outStream = socket.getOutputStream();

我正在尝试与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();
        }
      }
 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;
   
  }
但是在我的
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
如下:

  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();
        }
      }
 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;
   
  }
但它不起作用。插座似乎没有收到任何信息。

试试看

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
然后

使用utf-8创建的和作为字符编码

如果您想阅读整行内容,可以使用。 类似地,您可以在
OutputStreamWriter
周围使用或包装来将数据作为行写入。

您应该了解。简而言之,unicode字符点(Java
char
s,或多或少)是相同的,无论编码方式如何。编码更改给定
字节
序列转换为的字符

在代码中,有一个
字符串
,它实际上只是一个
字符序列。您可以使用
getBytes(“UTF-8”)
将其转换为
byte
s序列。当您读回它时,您正在读回每个
字节(作为
int
,但这是一个细节)——不是每个
char
。您尝试使用普通转换将这些字节转换为
字符
,该转换仅在字符的代码点值正好等于字节的int值时有效;对于UTF-8,这仅适用于“普通”字符

相反,您应该根据输入流中的字节和字符集重构
字符串。一种方法是先打电话,然后再打电话

您还可以使用表示可读字符流的
读取器
InputStreamReader
读取
InputStream
作为其字符流的源,然后
BufferedReader
可以获取该字符流并使用它生成
字符串,一次一行,正如程序员Jeff的回答所示。

试图为未来的访问者提供更多信息

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

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

用套接字编码 我想最重要的一点是:最后通过套接字发送字节,但这完全取决于这些字节的编码方式

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

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

回答这个问题 在Java中,有一些特殊的“桥接”流(read),可以用来指定流的编码

请注意:在Java
InputStream
OutputStream
中,所有使用这些流读取和写入的内容都是字节,您不能使用
InputStream
OutputStream
类的对象指定编码,因此可以使用Java桥类

下面是客户机和服务器的代码片段,在这里我试图演示如何在客户机的输出流和服务器的输入流上指定编码

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

客户端:

        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"));
服务器端:

        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"));
ServerSocket ServerSocket=新的ServerSocket(8001);
Socket clientSocket=serverSocket.accept();
//请注意:下面重要的一点是我在套接字的输入流上指定编码,因为Java是字节流,
//因此,为了指定编码,我使用Java I/O的桥接类并指定UTF8编码。
//所以,通过这个,我的所有数据(实际上是字节)都将从客户端套接字中以字节的形式读取,“但是”这些数据将以UTF8编码的字节的形式读取。
//假设我在这里指定了不同的编码,而不是客户机在其o/p流中指定的编码,则数据无法正确读取,可能是所有的“?”
InputStreamReader clientSocketReader=(新的InputStreamReader(clientSocket.getInputStream(),“UTF8”);
这对我很有效, 服务器端代码:

    try {   
    Scanner input = new Scanner(new File("myfile.txt"),"UTF-8");
    //send the first line only
    String line=input.nextLine();
    ServerSocket server = new ServerSocket(12345);
    Socket client = server.accept();
    PrintWriter out = new PrintWriter(
    new BufferedWriter(new OutputStreamWriter(
        client.getOutputStream(), "UTF-8")), true);
    out.println(line);
    out.flush();
    input.close();
    server.close();
    }catch (Exception e) {
        e.printStackTrace();
    }
客户端:

Socket mysocket = new Socket(SERVER_ADDR, 12345);
       bfr = new BufferedReader(new 
                InputStreamReader(mysocket.getInputStream(), "UTF-8"));
String tmp=bfr.readLine();
文本文件应编码为UTF-8

BufferedReader rd=null;
rd=新的BufferedReader(新的InputStreamReader(connection.getInputStream(),“UTF-8”);

好的,我试过了,但是没有