java UDP przesyłanie polskich znaków

0

Piszę aplikację w Javie. Jest to komunikator wykorzystujący klasy DatagramSocket, DatagramPacket i MulticastSocket. Przyczepię się tu do bzdury ale po przebyciu pakietu w jedną stronę polskie znaki zmieniają mi się na "krzaczki". Co ciekawe kiedy serwer wyśle multicastingiem te krzaczki to odebrane z powrotem u klienta to są znowu polskie znaki. Ktoś zna przyczynę i ewentualne rozwiązanie?

0

A wysyłasz i odbierasz to jako UTF-8?

4

Pewnie tworzysz stringi za pomoca new String(byte[]) i serwer i klient uzywaja innego domyslnego kodowania (osobne maszyny? systemy operacyjne? moze inne javy?). Jedna strona ma stringa i tworzy z niego bajty za pomoca "mućka".getBytes() i uzywa do tego np. kodowania cp1252 i wysyla takie i takie bajty; druga strona odbiera bajty i wola new String(bytes) ale uzywa kodowania utf-8 - jednak te bajty nie sa w utf-8 tylko w cp1252 wiec sa krzaki. Jednakze, pobranie tych bajtow i wyslanie w druga strone spowoduje ze druga strona odbierze bajty i new String(bajty) uzywa utf-8, czyli poprawnego kodowania, i wszystko dziala. (Oczywiscie, w momencie tworzenia string z bajtow w zlym kodowaniu i nastepnie pobranie bajtow z takiego stringa moze dac w wyniku inne bajty niz oryginalnie poniewaz moglo dojsc do straty informacji, ale z tego co rozumiem tak sie tutaj nie dzieje).
Aby temu zapobiec musisz np. ustalic ze dane zawsze sa wymieniane w jakims kodowaniu unicode (np. utf-8, jak wspomnial @Shalom) - umowmy sie, nie uzywasz unicode - robisz to zle! Albo wraz z kazdym pakietem danych wysylasz rowniez kodowanie (np. tak dziala protokol http), jednak to chyba niepotrzebne, utf-8 potrafi zareprezentowac chyba wszystko co potrzebujesz (albo masz bardzo egzotyczne potrzeby ;d). Dodatkowo, uzywasz metod String.getBytes(Charset) (np. "mućka".getBytes(StandardCharsets.UTF_8) a Java 7) oraz konstruktora String(bytes, Charset) (np. new String(bytes, StandardCharsets.UTF_8). Jelsi uzywasz Readera / Writera a nie Input/OutputStream, to musisz uzyc InputStreamReader / OutputStreamWriter ktore biora Input/OutputStream z socketa jako argument, oraz kodowanie - inaczej uzywaja platformowych defaultow i wracasz do punktu wyjscia.

Ja tylko zgaduje, moze zupelnie zle, musialbys powiedziec wiecej na temat OS, czy masz 2 kompy czy jeden, a moze wirtualki? Czy serwer uruchamiasz z konsoli a klienta np. w eclipse (np. windows uzywa - uzywal? - jakiegos innego kodowania, ale eclipse pod windowsem uzywal utf-8, zdaje sie, i widzialem mnostwo podobnych bledow), jak tworzysz stringi i jak robisz z nich bajty, jak wysylasz dane, jak je pobierasz (zwykle InputStreamy? Readery / writery? te drugie uzywaja domyslnego kodowania znakow. Itp. itd.

0

Działam pod win7, oba moduły (server i klient) mają gui więc każdy input odbywa się za pośrednictwem obiektów swing. I faktycznie serwer odpalam z konsoli, a klienta na eclipsie. W Eclipsie mam domyślnie poustawiane kodowanie UTF-8. No i pod konsolą odpalam binarki wygenerowane przez środowisko, ergo - wszystko z tej samej kompilacji. Pomysł z konstruktorem String'a wydaje mi się do rzeczy; sprawdzę go dzięki.

0

i faktycznie to załatwia sprawę, dzięki za pomoc :)

0

Tak po za tematem, do komunikatorów nie lepiej używać TCP niż UDP ?

0

Oczywiście, ale takie mam zadanie na uczelni(to w zasadzie 1/4 zadania). Pomęczyć się z pisaniem i wywnioskować, że połowa jest nie tak, jak należy...

0

@Kandif @dante02891 to zależy do jakiej komunikacji. TCP ma swoje zalety ale ma też wady. Jak przesyłasz pliki to chcesz zeby całe doszły więc TCP z retransmisjami jest ok. Ale jak streamujesz audio/video to nie chcesz zeby się rozjeżdżały tylko dlatego że pakiety dochodzą w złej kolejności. W tym wypadku lepiej jak jakiś pakiet zginie niż żeby się pojawił za późno. No i UDP pozwala nadawać multicastem ;) Jest też dużo "lżejsze" bo nie wymaga wymiany uścisków dłoni i synchronizacji. W efekcie jak chcesz często nawiązywać połączenie i wysyłac niewiele danych to narzut TCP moze okazać sie bardzo duży.

1 użytkowników online, w tym zalogowanych: 0, gości: 1