Dies ist ein interessantes Problem, das ich bisher nicht lösen konnte.Delphi Indy IdTcpClient-Leseoperation, die abgeschnittene Daten für eine bestimmte Anfrage zurückgibt
Ich schreibe einen Client, der über das Internet an einen Server kommuniziert. Ich verwende die TIdTcpClient Internet Direct (Indy) -Komponente in Indy 10 mit der ursprünglichen Persönlichkeit von RAD Studio 2007.
Um Daten vom Server abzurufen, erstelle ich eine HTTP-Anfrage mit SSL über Port 443, wo meine Anfragedetails im HTTP-Nachrichtentext enthalten sind. So weit, ist es gut. Der Code funktioniert mit einer Ausnahme wie Charme.
Es gibt eine Anfrage, die ich einreiche, die eine Antwort von etwa 336 KB vom Server produzieren sollte (der HTTP-Antwortheader enthält Content-Length: 344795). Das Problem ist, dass ich nur 320KB zurückbekomme. Die Antwort, die in XML ist, wird in der Mitte eines XML-Elements deutlich abgeschnitten.
Für was es wert ist, ist das XML einfacher Text. Es gibt keine Sonderzeichen, die für die Kürzung verantwortlich sein können. Meine TIdTcpClient-Komponente berichtet einfach, dass der Server die Verbindung ordnungsgemäß geschlossen hat, nachdem die Teilantwort empfangen wurde (auf diese Weise wird erwartet, dass jede Antwort abgeschlossen wird, auch wenn diese nicht abgeschnitten wird. Dies ist also kein Problem).
Ich kann fast identische Anrufe an den gleichen Server, wo die Antwort auch mehr als ein paar K Bytes ist, und alle diese funktionieren gut. Eine Anfrage, die ich mache, gibt ungefähr 850 KB zurück, eine andere gibt ungefähr 300 KB zurück und so weiter.
Kurz gesagt, ich stoße dieses Problem nur mit der einen spezifischen Anfrage. Alle anderen Anfragen, von denen es viele gibt, erhalten eine vollständige Antwort.
Ich habe mit dem Ersteller des Dienstes gesprochen und Beispiele meiner Anfrage geliefert. Er hat berichtet, dass die Anfrage korrekt ist. Er sagte mir auch, dass er, wenn er meine Anfrage an seinen Server richtet, eine vollständige Antwort bekommt.
Ich bin ratlos. Entweder ist der Ersteller des Dienstes falsch, und es gibt tatsächlich ein Problem mit der Antwort zu diesem Zweck, oder es ist etwas eigenartig an meiner Anfrage.
Gibt es hier eine Lösung, die ich vermisse? Beachten Sie, dass ich auch eine Reihe anderer Lesemechanismen (ReadString, ReadStrings, ReadBytes usw.) verwendet habe und alle das gleiche Ergebnis, eine Kürzung dieser einen spezifischen Antwort bei der 320KB-Markierung, erzeugen.
Der Code ist wahrscheinlich nicht relevant, aber ich werde es trotzdem aufnehmen. Entschuldigung, aber ich kann die XML-Anfrage nicht einschließen, da sie proprietäre Informationen enthält. (Readtimeout auf 20 Sekunden eingestellt, aber die Anforderung kehrt in etwa 1 Sekunde, also ist es kein Timeout Problem.)
function TClient.GetResponse(PayloadCDS: TClientDataSet): String; var s: String; begin try try s := GetBody(PayloadCDS); IdTcpClient1.Host := Host; IdTcpClient1.Port := StrToInt(Port); IdTcpClient1.ReadTimeout := ReadTimeout; IdTcpClient1.Connect; IdTcpClient1.IOHandler.LargeStream := True; //IdTcpClient1.IOHandler.RecvBufferSize := 2000000; IdTcpClient1.IOHandler.Write(s); Result := IdTcpClient1.IOHandler.AllData; except on E: EIdConnClosedGracefully do begin //eat the exception end; on e: Exception do begin raise; end; end; finally if IdTcpClient1.Connected then IdTcpClient1.Disconnect; end; end;
TIdHTTP unterstützt SSL auf die gleiche Weise wie TIdTCPClient - durch Zuweisung eines SSL-fähigen IOHandlers vor der Verbindung. Sie sollten wirklich die TIdHTTP-Komponente für die Verarbeitung von HTTP-Datenverkehr verwenden. Deshalb existiert es an erster Stelle. –
In der aktuellen Indy 10-Version ist der Standardwert der Eigenschaft SSLOptions.Method nicht sslvSSLv2, sondern sslvTLSv1. Es macht Sinn, dass das Setzen der Methode auf sslvSSLv23 einige Fehler beheben würde. Wenn die Methode auf etwas anderes als sslvSSLv23 eingestellt ist, muss * die andere Partei * diese spezifische SSL-Version am Ende verwenden oder der SSL-Handshake wird fehlschlagen. sslvSSLv23 dagegen ist eher ein Catch-All-Platzhalter, der alle SSL-Versionen von SSLv2 bis TLSv1 unterstützt und beide Parteien eine kompatible SSL-Version aushandeln kann. –