Diskuze: Problém s kódováním server-klient

Java Java Problém s kódováním server-klient

Avatar
Lukas C#
Redaktor
Avatar
Lukas C#:

Ahojte, splácal jsem primitivní klient a server. Klient se připojí k serveru (na localhostu) a posílá zprávy, které zadá uživatel. Problém nastává při posílání textu s diakritikou: Klient i server je spuštěný každý v instanci CMD / powershell (zkoušel jsem obojí). před spuštěním zadám příkaz "chcp 65001", což má změnit code page na Unicode při použití UTF-8. Všechny streamy, které v klientu a serveru zapisují, jsou Buffered Streamy s explicitně nastaveným UTF-8 kódováním. Stejně při odeslání textu, co obsahuje diakritiku, není stream reader schopný načíst text, a String, kam si to ukládám, je null. Zkoušel jsem snad všemožné kombinace např. se Scannerem, nic nefunguje. Buď stream nic nepřečte a vrátí null, nebo se na serveru zpráva zobrazí špatně. Něco důležitého mi tu uniká. Nemohl by mi někdo pomoct?

Tady je Klient:

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;


public class Client
{
        public static void main(String[] args) throws Exception
        {
                BufferedReader input = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
                BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
                output.write("Press enter to connect");
                output.flush();
                input.readLine();

                Socket clientSocket = new Socket("localhost", 5000);

                output.write("Connected to server\n");
                output.flush();

                BufferedWriter senderWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8));
                String message = "";
                while(!message.equals("--disconnect"))
                {
                                output.write("Type message: ");
                                output.flush();

                                //Pokud String vytvořím v programu, na Serveru se zobrazí správně:
                                // String s = "český textík s řádnou diakritikou";
                                // sendWriter.write(s);

                                //ZDE - funkce vrací null, pokud do cmd/powershell napíšu znak s diakritikou a odešlu enterem
                                // program následně spadne u zápisu message s NullPointerException
                                message = input.readLine();
                                //_______________________________________

                                senderWriter.write(message);
                                senderWriter.newLine();
                                senderWriter.flush();
                }
                System.out.println("You have disconnected from the server");
        }
}

Tady je server:

import java.net.*;
import java.nio.charset.StandardCharsets;
import java.io.*;


public class Server
{

        public static void main(String[] args) throws Exception
        {
                ServerSocket serverSocket = new ServerSocket(5000);
                Socket clientSocket = serverSocket.accept();

                System.out.println("Client connected from address " + clientSocket.getLocalAddress().getHostAddress() + " under port " + Integer.toString(clientSocket.getLocalPort()));

                BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8));
                BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8));

                String message = "";
                int mes = 0;
                while(!(message = br.readLine()).equals("--disconnect"))
                {
                        wr.write("Client sends a message:" + message + "\n");
                        wr.flush();
                }

                System.out.println("Client disconnected!");

                clientSocket.close();
        }
}
 
Odpovědět 29. července 13:55
Avatar
Petr Štechmüller:

Ahoj, problém je v příkazové řádce woken, že má výchozí znakovou sadu cp1250.
Místo scanneru, nebo buffered readeru použij objekt Console.

Zde je použití:

// Získání instance
private static Console console = System.console();

// Vypsání textu
console.printf("Connected to server\n");

// Získání textu
message = console.readLine();
Nahoru Odpovědět 29. července 17:24
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Lukas C#
Redaktor
Avatar
Odpovídá na Petr Štechmüller
Lukas C#:

Jop, právě proto sadu přepínám jak u klienta tak u serveru - "chcp 65001". Console problém neřeší, readLine vrátí stejně null. Nicméně alespoň funguje, když nechám právě výchozí code page 1250 (což BufferedReader ani Scanner nedokázal). Takže alespoň to dokáže komunikovat jazyky, pro které je 1250 dělaná, když už ne globálně Unicode :-)

 
Nahoru Odpovědět 29. července 20:24
Avatar
Odpovídá na Lukas C#
Petr Štechmüller:

Tak to je divný, me to funguje parádně.

Editováno 29. července 20:26
Nahoru Odpovědět 29. července 20:26
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Lukas C#
Redaktor
Avatar
Odpovídá na Petr Štechmüller
Lukas C#:

Máš anglickou verzi Windows nebo českou? Já mám anglickou verzi a přepínam jenom na českou klávesnici. Ale nenapadá mě, proč by to na to mělo mít vliv, když tu code page stejně přenastavuju. Možná jak Win zachází s klávesnicí?? Nwm.

 
Nahoru Odpovědět 29. července 20:28
Avatar
Odpovídá na Lukas C#
Petr Štechmüller:

Ja mám českou verzi. Možná to může mít nějaký vliv...

Nahoru Odpovědět 29. července 20:29
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
pocitac770
Redaktor
Avatar
pocitac770:

Pokud by nic nepomáhalo, je tu jistý... Způsob, jak to vyřešit :D
Napadlo mě to jednou použít při komunikaci MC klient - Android app (takže nezávisle na tom, co jste zatím popsali ohledně pouitých "konzolí"), stačí si každý posílaný znak převést na jeho UNICODE číselnou hodnotu, tu odeslat, poté na straně klienta zase převést zpět, sice to zvyšuje datový přenos, ale mělo by to fungovat vždy

Editováno 30. července 0:22
 
Nahoru Odpovědět 30. července 0:22
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.