Entwickler-Ecke

Internet / Netzwerk - TCP Verbindung, empfangen klappt nicht, andere TCP Nachricht


daywalker0086 - Do 14.06.18 18:43
Titel: TCP Verbindung, empfangen klappt nicht, andere TCP Nachricht
Hallo an alle Netzwerkaffinen.
ich schreibe einen TCP Client, der mit einem Server kommunizieren soll.
Als Vorlage habe ich auch eine fertige Clientapplikation von der ich die gesendeten Telegramme mitgeschnitten habe.
Das Progblem dabei, ich sende zwar etwas, aber bekomme keine richtige Antwort.
Als bzw. wird mir in meinem Programm nichts angezeigt, obwohl vom Server Antworten kommen.
Im Mitschnitt sieht man alleridngs auch Unterschiede:
Das Fertige Gui Programm sendet nach der ersten Servernachricht nochmal ein ACK. Ich nicht und bei dem fertigen Programm sendet der Server auch ein Telegramm mit Finished Flag.
Das kommt bei mir auch nicht.

Die Frage ist jetzt was muss ich verändern damit die Komunikation so aussieht wie im vorgegebenen Programm?
Hier mal mein Sendecode:
Als Komponente nutze ich TTcpClient aus der Kategorie Internet

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.sendmessage(sendstring: string);
var
bin: string;
i : integer;
length_m: integer;
begin
  if Odd(Length(sendstring)) then // Länge ungerade?
  sendstring := '0'+sendstring; // auffüllen

  for i := 0 to (Length(sendstring) -1shr 1 do
     bin := bin +Chr(StrToInt('$'+Copy(sendstring,(i shl 1) +1,2)));
  TCPclient1.SendBuf(bin[1],length(bin));
end;


procedure TForm1.get_proj_btnClick(Sender: TObject);
var
BUFFER, bin: string;
  i: Integer;
  receive :string[12];
begin
  sendmessage(functions.get_gsdversion()+functions.get_free_device()+gsd_get_sdata());
  while TcpClient1.WaitForData(800do
 begin
  TcpClient1.ReceiveBuf(receive[1], sizeof(receive)); // Nachricht darauf empfangen

  end;
end;


Im Anhang die Dumps die man mit Wireshark schön anschauen kann
am besten bei Filter tcp.port eq 26000 eintragen dann sieht man den Rest nicht...


Narses - Do 14.06.18 23:04

Moin!

user profile icondaywalker0086 hat folgendes geschrieben Zum zitierten Posting springen:
Als Komponente nutze ich TTcpClient aus der Kategorie Internet
Ist schon etwas her, aber AFAIR ist die Delphi-Onboard-Kompo entweder kaputt oder so schräg programmiert, dass man sie nicht benutzen kann. :nixweiss: (ich hab´s damals jedenfalls nicht hingekriegt)

Nimm Indy, die alten Socket-Kompos oder sonstwas, dann sollte das klappen. :idea:

cu
Narses


jaenicke - Fr 15.06.18 07:19

Das Problem dürfte sein, dass der Empfangspuffer noch nicht geleert ist. In dem Fall wird kein ACK gesendet. Deshalb würde ich sehr empfehlen den TCPClient Code in einen Thread zu packen und alle empfangenen Daten zu lesen und nicht immer nur deine 12 Byte.

Ich würde aber eher asynchrone Sockets empfehlen, konkret die ICS Komponenten [http://www.overbyte.eu/frame_index.html].


daywalker0086 - Fr 15.06.18 09:11

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das Problem dürfte sein, dass der Empfangspuffer noch nicht geleert ist. In dem Fall wird kein ACK gesendet. Deshalb würde ich sehr empfehlen den TCPClient Code in einen Thread zu packen und alle empfangenen Daten zu lesen und nicht immer nur deine 12 Byte.



Wie mache ich das denn? Ich weis ja vorher nicht wie viele kommen?


daywalker0086 - Fr 15.06.18 09:57

Okay hab jetzt die IndyKomponente genommen.
Jetzt erhalte ich auch eine Antwort vom Server :D (Sehe ich auf meinem Socket Sniffer)

Jetzt wollte ich natürlich erstmal di eAntwort entgegen nehmen aber da friert mein Programm ein.
Wie mach ich das denn richtig?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.sendmessage(sendstring: string);
var
bin: string;
i : integer;
length_m: integer;
send_array :tbytes;
begin
  IdTCPClient1.Connect;
  if IdTCPClient1.Connected then
  begin
    if Odd(Length(sendstring)) then // Länge ungerade?
    sendstring := '0'+sendstring; // auffüllen

    for i := 0 to (Length(sendstring) -1shr 1 do
    bin := bin +Chr(StrToInt('$'+Copy(sendstring,(i shl 1) +1,2)));

    IdTCPClient1.IOHandler.Write(bin);
    IdTCPClient1.IOHandler.ReadLn(bin);
  end;
end;


Narses - Fr 15.06.18 17:35

Moin!

Die Indy-Komponenten sind blocking, wenn dein Programm beim warten auf Daten weiter Messages verarbeiten soll, muss der kommunikationsrelevante Teil in einen Thread. :idea:

Weiterhin wartet .ReadLn(); auf einen Zeilenumbruch (Terminatorzeichen), also je nach Vorgabe CR, LF oder CRLF. Ist das in deinem Protokoll denn überhaupt vorgesehen?

cu
Narses