2013-11-25 3 views
2

Я пытаюсь отправить строку с сервера, который имеет символов по умолчанию кодировку UTF-8 а клиенту, который имеет характер по умолчанию кодировку окон-1252 в через Розетка и PrintWriter.PrintWriter над Гнездо OutputStream Причины коррупции/Потеря данных

Когда я запускаю клиента ниже, я не получаю свое первоначальное значение 141 назад, несмотря даже на мои попытки преобразовать строку с помощью CharsetDecoder.

В качестве контрольного теста я попытался запустить оба этих класса в Eclipse и обеспечить использование как UTF-8 в качестве системы кодирования по умолчанию через диалог ниже - и я заметил, что, когда оба клиента используют UTF -8, вывод успешно интерпретируется на стороне клиента.

Обновление: Похоже, что я могу передавать байты и восстанавливать исходный формат, но для этого мне нужно было бы знать, какая кодировка используется на сервере. Разве нет какой-то библиотеки, которая была бы полезна в этой ситуации? Я бы скорее не был вынужден передавать данные в виде байтовых массивов.

Eclipse Dialog

Сервер:

import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

//Runs on a server with default character encoding of UTF-8 
public class TestServer { 

public static void main(String[] args) throws Exception { 

    PrintWriter writer = null; 
    ServerSocket serverSocket = null; 
    try { 

     int x = 141; 
     String s = "#" + (char)x; 

     serverSocket = new ServerSocket(5555); 
     Socket clientSocket = serverSocket.accept(); 

     writer = new PrintWriter(
         (new OutputStreamWriter(clientSocket.getOutputStream())), true); 

     System.out.println((int)s.charAt(1)); 
     writer.write(s); 
    } catch(Exception e) { 

     e.printStackTrace(); 
    } finally { 

     writer.close(); 
     serverSocket.close(); 
    } 
} 
} 

Клиент:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.net.Socket; 
import java.nio.ByteBuffer; 
import java.nio.CharBuffer; 
import java.nio.charset.Charset; 
import java.nio.charset.CharsetDecoder; 

//Runs on a server with default character encoding of windows-1252 
public class TestClient { 

public static void main(String[] args) throws Exception { 

    Socket s = new Socket("localhost", 5555); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream())); 

    String string = reader.readLine(); 
    System.out.println((int)string.charAt(1)); //prints 194 when it was 141 on the other end 

    //Charset.defaultCharset returns windows-1252 
    CharsetDecoder decoder = Charset.defaultCharset().newDecoder(); 
    CharBuffer buffer = decoder.decode(ByteBuffer.wrap(string.getBytes())); 
    String convertedString = buffer.toString(); 

    System.out.println((int)convertedString.charAt(1)); //still prints 194 

    String convertedString2 = new String(string.getBytes(), "UTF-8"); 
    System.out.println((int)convertedString2.charAt(1)); //prints 65533 ?? 

    s.close(); 
} 
} 

ответ

2

I обнаружил, что есть конструкторы OutputStreamWriter и InputStreamReader, которые принимают наборы символов в качестве параметра. Это решение, которое я пошел с:

На отправителем:

out = new PrintWriter(
    new BufferedWriter(new OutputStreamWriter(
     socket.getOutputStream(), "UTF-8")), true); 

На приемнике:

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

Я просто write()byte[] непосредственно к OutputStream и избежать средних людей, а затем построить новый Строка на стороне клиента fr om возвращает byte[]. PrintWriter документы говорят:

Он не содержит методы для записи необработанных байт, для которых программа должна использовать незакодированные потоки байт.

В новом коде сервера вы должны:

bytep[] s = new String("#" + (char)x).getBytes();; 
    Socket clientSocket = serverSocket.accept(); 
    OutputStream writer = clientSocket.getOutputStream(); 
    System.out.println((int)s.charAt(1)); 
    writer.write(s); 

На стороне клиента, вы бы создать ByteArrayInputStream и преобразовать байт в строку:

byte[] return_data = null; 
Socket s = new Socket("localhost", 5555); 
BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
int byte_read = bis.read(); 
while(byte_read != -1) 
{ 
    baos.write(byte_read); 
    byte_read = bis.read(); 

} 

return_data = baos.toByteArray(); 
bis.close(); 
baos.close(); 

String s = new String(return_data); 
+0

Хм .. Я видел, что, как вариант, но я действительно пытался избежать , Существуют ли другие реализации OutputStream более высокого уровня, которые я мог бы использовать? – kwikness

+0

Я думаю, что на самом деле немного меньше кода для использования метода byte []. См. Образец кода, который я предоставил. – mttdbrd

+0

Спасибо.Я предполагаю, что это сработает, но ваше решение не обеспечивает способ декодирования на стороне клиента, не зная кодировку символов сервера. Кроме того, мне бы очень понравилось решение, которое не требует чтения/записи байтов. – kwikness

 Смежные вопросы

  • Нет связанных вопросов^_^