Komunikacja java - delphi

0

Mam problem z komunikacja miedzy aplikacjami - pierwsza delphi, druga java. Łączą się bezproblemowo przy pomocy socketów, niestety potem jest problem z przesyłaniem. Co mam zmienić, abym mogł przesyłać stringa? W kodzie javy zamiast "dupa" otrzymuję cos typu "�*��"

Kod javy:

ServerSocket serverSocket = new ServerSocket(1025);
Socket client = serverSocket.accept();

BufferedReader dn= new BufferedReader(new InputStreamReader(client.getInputStream()));

System.out.println(d.readLine());

Kod delphi:

var
    wsa : WSAData;
    Adr: String;
    socket_info: sockaddr_in;
    Gniazdo: Integer;
    port: Integer;
    ErrorCode: Integer;
    bufor: String;

WSAStartup(MAKEWORD(2,0),wsa);
Adr := '127.0.0.1';
port := 1025;
Gniazdo := Socket(AF_INET, SOCK_STREAM,0);
socket_info.sin_family := AF_INET;
socket_info.sin_addr.s_addr := inet_addr(PChar(Adr));
socket_info.sin_port := htons(port);
ErrorCode :=connect(Gniazdo, socket_info, SizeOf(socket_info));
if (ErrorCode = SOCKET_ERROR) then
     MessageBox(0,'Połączenie nieudane', 'Msg', MB_OK)
else
     begin
     bufor := 'dupa';
     MessageBox(0, 'Połączenie nawiązane', 'Msg', MB_OK);
     send(Gniazdo, bufor, sizeof(bufor), 0);
     end;
CloseSocket(Gniazdo);
WSACleanUp;
0

Po pierwsze w pierwszym kodzie, w ostatniej linijce chciałeś napisać "dn" a nie "d", prawda ?
Proponuje pobawic sie z ustawieniami kodowania znakow w InputStreamReaderze: http://download.oracle.com/javase/1.5.0/docs/api/java/io/InputStreamReader.html#InputStreamReader%28java.io.InputStream,%20java.nio.charset.Charset%29

0

zaden z kodowań się nie sprawdza:
US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
UTF-8 Eight-bit UCS Transformation Format
UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order
UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order
UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark

Co tu teraz począć? Mogę odbierać pojedyncze chary, ale będzie duzo przesyłania dlugich stringow(xml)..

0

Zmień

 send(Gniazdo, bufor, sizeof(bufor), 0); 

na:

 send(bufor, Gniazdo(NULL), 55) 
0

Nie kompiluje się:

[Error] Unit1.pas(437): Incompatible types: 'Integer' and 'String'
[Error] Unit1.pas(437): Not enough actual parameters

0

A może jakieś przekształcenia w stylu:

bufor := 'tekst'+#13#10; // w sensie nowej linii na koncu
send(Gniazdo, PChar(bufor), length(bufor), 0);
0

[Error] Unit1.pas(438): Constant object cannot be passed as var parameter.

Po usunięciu PCharu() działa, ale dalej przesyła krzaczki

0

wyświetl sobie sizeof(string) w Delphi, czeka cię niespodzianka.

0

ściągnij sobie np. ten tcp test server, zainstaluj, odpal, skonfiguruj i spróbuj się połączyć aplikacją pisaną w delphi i coś wysłać. Zobaczysz co przychodzi. Jak ok to problem po stronie javy i najprawdopodobniej kodowania (odczytaj tekst jako bajty i zobacz co przychodzi). A jak przyjdą krzaki to gdzieś w delphi masz błąd

0

@Azarien
a na co to ma wplyw? ja tylko wypisuje wynik funkcji wczytania

@Misiekd
juz sciągam i konfiguruję. Tak a propoS jak probowałem w jakis sposób(juz nie pamietam, ktory to byl-_-) przeslac pojedynczego chara to przychodzil mi kod ascii danego chara. Czyli to moze kodowanie jednak? Tylko co mam zmienic? Wszystkie wyzej wymienione kodowania
przelecialem.

edit: w tcp test serwerze jako msg pokazuje się jakiś krótki krzak. A jak probuję pisać od javy do delphi to już w ogole komp sie wiesza prawie:D


moze jakiś inny sposób komunikacji polecacie?

0

Postarałem się uzyć troszke innego sposobu.. błędy dalej oczywiscie.

Delphi:

ClientSocket1: TClientSocket;
(...)
ClientSocket1.Port:=1025;
ClientSocket1.Address:= '127.0.0.1';
ClientSocket1.Active:= True;
(...)
Socket.SendText('lalalala');

Java:

ServerSocket serverSocket = new ServerSocket(1025);

System.out.println("Czekam na klienta...");
Socket client = serverSocket.accept();

ObjectInputStream readStream = new ObjectInputStream(client.getInputStream());
System.out.println(readStream.readObject());

I teraz tak:
Łączą się elegancko. Gdy program delphi przesyla tekst wysypuje:
".. raised exception class ESocketError with message 'Asynchronous socket error 10053'

a program java sypie wyjatek:
invalid stream header: 6C616C61

WTF?? Ręce mi opadają, niestety muszę jakoś połączyć te programy. Może jest jakis inny sposób?

0

a na co to ma wplyw? ja tylko wypisuje wynik funkcji wczytania
ale długość tekstu w bajtach to nie sizeof(string), tylko length(bufor)*sizeof(char) bajtów.

zaden z kodowań się nie sprawdza:
no jak to nie. Delphi ma funkcje do obsługi UTF-8 i UTF-16.

0

mozesz mi napisac, jak ustawic to kodowanie?

0

Tylko rzuciłem okiem i na pierwsze spojrzenie masz błąd w send.

Powinno być:

Send(SocketHandle, Pointer(Msg)^, length(Msg), 0);

gdzie msg to zmienna string.

0

jestem zielony, ale kiedyś coś takiego miałem do wysyłania (wygrzebane z dysku). Wklejam na szybko fragment kodu (wywalone kilka linijek)... do wysyłania zapytań do serwera strony www używałem

var
  zapytanie: String;
  wyslano: Integer;
  x: PAnsiChar;
begin

  zapytanie:=
    Format('GET /sr/f/%s HTTP/1.1', [adres_end]) + #13#10 +
    Format('Host: %s', [adres_host]) + #13#10 +
    'User-Agent: Mozilla/5.0' + #13#10 +
    'Accept: text/html' + #13#10 +
    //'Accept-Encoding:' + #13#10 +
    'Keep-Alive: 115' + #13#10 +
    'Connection: keep-alive' + #13#10 + #13#10;

  GetMem(x, 255);
  StrPCopy(x, zapytanie);

  wyslano:= send(klient, x^, Length(zapytanie), 0);
  if (wyslano < 0) then ShowMessage('Nie wysłano...');

  FreeMem(x, 255);
end;

jakby co to olejcie tego posta (nie chcę się kompromitować :D)

0

no i dupa. Dalej rzuca w javie wyjątek typu "invalid stream header"

czy byłby ktoś tak wielkoduszny i mógłby sprawdzić ten kod u siebie?
java:

try {
            ServerSocket serverSocket = new ServerSocket(1025);
            System.out.println(InetAddress.getLocalHost().getHostAddress());
            while(true){
                System.out.println("Czekam na klienta...");
                Socket client = serverSocket.accept();
                
                InputStreamReader isr = new InputStreamReader(client.getInputStream());
                BufferedReader d = new BufferedReader(isr);
                System.out.println(d.readLine());
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

delphi:

var
  Form1: TForm1;
  wsa : WSAData;
  Adr: String = '127.0.0.1';
  socket_info: sockaddr_in;
  Gniazdo: Integer;
  port, ErrorCode: integer;

     WSAStartup(MAKEWORD(2,0),wsa);
     Gniazdo := Socket(AF_INET, SOCK_STREAM,0);
     socket_info.sin_family := AF_INET;
     socket_info.sin_addr.s_addr := inet_addr(PChar(Adr));
     port := 1025;
     socket_info.sin_port := htons(port);
     ErrorCode :=connect(Gniazdo, socket_info ,SizeOf(socket_info));
     if (ErrorCode = SOCKET_ERROR) then
        MessageBox(0,'Połączenie nieudane','Error',MB_OK)
     else
     begin
          MessageBox(0,'Połączenie udane','Error',MB_OK);
          send(Gniazdo, Pointer(Adr)^, length(Adr), 0);
    end;
    WSACleanUp;   

Wiem, ze to moze zabrzmieć żałosnie, ale bardzo proszę o poświęcenie 5 minut dla mnie i sprawdzenie tego samego u siebie. Jestem uziemiony z projektem zaliczeniowym dopóki nie ogarnę tego.

0

Odpowiedź jednego z wykładowców u mnie na uczelni:

"To co Pan w Delphi wysyla w zadnym razie nie musi byc rozumiane na poziomie binarnym przez Javovego readera. Np. nie ustawia Pan charsetu dla readera. Kontroluje pan co jest w buforze (bajt-po bajcie), reprezentowanym przez stringa? I jest to w rozumieniu Javy linia? A wie Pan czy czasem buff nie zawiera gdzies liczby mowiacej jakiego rozmiaru jest napis? Delphi nie znam ale w Pascalu tak bylo. Uzywanie ObjectStreamow Javy jest tym bardziej bez sensu - to bedzie kompatybilne tylko z Java.

Rozwiazania moga byc dwa:
-) "reczne": w delphi konwertuje Pan to co chce wyslac do ciagu bajtow, ktory Pan rozumie. Tzn. jest Pan w stanie odpowiedziec na pytanie co jest na ktorej pozycji i co znaczy. Odbiera Pan to w Javie czystym, binarnym InputStreamem. Ma Pan ta sama sekwencje bajtow i moze Pan sobie (znowu recznie) przekonwertowac do czegos co sie da uzywac wygodniej niz tablice bajtow.

-) porzadnie: nalezy uzyc web services. To zapewnia elegancka mozliwosc wspolpracy pomiedzy platformami. Serwer po stronie Javy, klient w delphi."

Sprobuję na razie ten sposób pierwszy. Po stronie javy wiem jak operować i przesyłać bajty w utf-8, ale nie wiem jak w delphi. Probowałem już wielu rzeczy proponowanych w necie. Ogolnie mój problem jest teraz taki: jak w delphi przekształcic WideStringa do tablicy bajtow w utf-8.

0
var tekst:widestring;
    bufor:utf8string;

  tekst:='zażółć gęślą jaźń';
  bufor:=utf8encode(tekst);
  { bufor:=utf8encode('zażółć gęślą jaźń'); }
  send(Gniazdo, pansichar(bufor)^, length(bufor), 0);

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