Delphi Indy Idtcpclient قراءة العملية إرجاع البيانات المقطوعة طلب واحد محدد

StackOverflow https://stackoverflow.com/questions/1278333

  •  16-09-2019
  •  | 
  •  

سؤال

هذه مشكلة مثيرة للاهتمام أنني لم أتمكن من حلها بعد.

أنا أكتب عميلا يتصل عبر الإنترنت إلى خادم. أنا أستخدم مكون TidTCPClient Internet Direct (Indy) في Indy 10 باستخدام شخصية Rad Studio 2007 الأصلية.

للحصول على بيانات من الخادم، أصدر طلب HTTP باستخدام SSL عبر المنفذ 443 حيث توجد تفاصيل طلبي في جسم رسالة HTTP. حتى الان جيدة جدا. الرمز يعمل مثل سحر، مع استثناء واحد.

هناك طلب واحد أقدم فيه أنه يجب أن ينتج استجابة من حوالي 336 كيلو بايت من الخادم (يحتوي رأس استجابة HTTP على محتوى طول: 344795). المشكلة هي أنني أحصل على 320 كيلو بايت فقط. يتم اقتطاع الاستجابة، الموجودة في XML، بوضوح في منتصف عنصر XML.

لما يستحق، فإن XML هو نص بسيط. لا توجد أحرف خاصة يمكنها حساب الاقتطاع. إن مكون TidTCPClient الخاص بي هو ببساطة الإبلاغ عن أنه، بعد تلقي الاستجابة الجزئية، أن يقوم الخادم بإغلاق الاتصال بأمان (وهو كيفية اكتمال كل استجابة، حتى تلك التي لا يتم اقتطاعها، لذلك هذه ليست مشكلة).

يمكنني إجراء مكالمات متطابقة تقريبا إلى نفس الخادم حيث تكون الاستجابة أكثر من بضعة بايت K، وكل هذه العمل على ما يرام. طلب واحد أقوم بإرجاع حوالي 850 كيلو بايت، وإرجاع آخر حوالي 300 كيلو بايت، وهلم جرا.

باختصار، واجهت هذه المشكلة فقط مع طلب واحد محدد. جميع الطلبات الأخرى، منها العديد منها، تلقي استجابة كاملة.

لقد تحدثت إلى خالق الخدمة، وقد قدمت أمثلة على طلبي. وذكر أن الطلب صحيح. أخبرني أيضا أنه عندما يصدر نفس طلبي إلى خادمه أنه يحصل على استجابة كاملة.

أنا في حيرة. إما أن خاطئ الخدمة مخطئا، وهناك مشكلة في الاستجابة في هذه الغاية، أو هناك شيء غريب عن طلبي.

هل هناك حل هنا أفتقده؟ لاحظ أنني استخدمت أيضا عددا من آليات القراءة الأخرى (Readstring، Readstrings، ReadStrings، Readbytes، إلخ) وكلها تنتج نفس النتيجة، وهو اقتطاع هذا الاستجابة المحددة هذه في علامة 320 كيلو بايت.

ربما يكون الرمز مناسبا، لكنني سأدرجه على أي حال. آسف، لكن لا يمكنني تضمين طلب XML، لأنه يتضمن معلومات الملكية. (يتم تعيين adeattimeout إلى 20 ثانية، ولكن إرجاع الطلب في حوالي 1 ثانية، لذلك ليس مشكلة مهلة.)

وظيفة tclient.getResponse (payloadcds: tclientdataset): سلسلة؛ var s: سلسلة؛ ابدأ جرب جرب S: = GETBODBOD (PAYLOADCDS)؛ idtcpclient1.host: = المضيف؛ idtcpclient1.port: = Strtoint (منفذ)؛ idtcpclient1.ReadTimeout: = readtimeout؛ idtcpclient1.connect؛ idtcpclient1.iohandler.largestream: = صحيح؛ //idtcpclient1.iohandler.recvbuffersize: = 2000000؛ idtcpclient1.iohandler.write (ق)؛ النتيجة: = idtcpclient1.iohandler.alldata؛ إلا على E: EIDCONNCLOSTGRIDGRALE تبدأ / / أكل نهاية الاستثناء؛ على E: استثناء يبدأ زيادة؛ نهاية؛ نهاية؛ أخيرا إذا idtcpclient1.connected ثم idtcpclient1.disconnect؛ نهاية؛ نهاية؛
هل كانت مفيدة؟

المحلول 2

كما ذكرت في سؤالي الأصلي، يستخدم هذا الاتصال SSL. يتطلب هذا استخدام مكون IDSSLiohandLersocketopensSSSL، والتي تقوم بتعيينها إلى خاصية Iohandler لمكون IDTCPCLient. كل هذا كان في تصميمي الأصلي، وكما ذكرت، يجري استجابة العديد من طلباتي بشكل صحيح.

خلال عطلة نهاية الأسبوع، اكتشفت طلبا آخر كان يعيد استجابة غير مكتملة. استولت على طلب HTTP الأصلي، واستخدام أداة تسمى SOAP UI، قمت بتقديم الطلب إلى الخادم. باستخدام SOAP UI، عاد الخادم إجابة كاملة. بوضوح، كان هناك خطأ ما في موكلي، وليس الخادم.

أخيرا وجدت الحل عن طريق الخفز فقط مع مختلف الخصائص. كانت الممتلكات التي تحررت المشكلة أخيرا في خاصية SSLOptions من فئة IDSSLIOHandLersocketopenssl. القيمة الافتراضية لل SSLOPETASTION.METHOD هي SSLVSSLV2. عندما غيرت الطريقة إلى sslvsslv23، عاد جميع الردود كاملة.

لماذا تمكنت من استرداد بعض الردود بالكامل وليس كلها قبل أن أكون هذا التغيير لا يزال لغزا لي. ومع ذلك، فإن إعداد idssliohandlersocketopenssl.ssloptions.method إلى sslvsslv23 حل مشكلتي.

شكرا لك ريمي ليبو، للحصول على اقتراحاتكم.

نصائح أخرى

نظرا لأنك ترسل طلب HTTP، فيجب أن تستخدم مكون Tidhttp بدلا من مكون TidTcpclient مباشرة. هناك الكثير من التفاصيل حول بروتوكول HTTP الذي يديره TITHTTP لك أن يتعين عليك التعامل معه يدويا إذا استمرت في استخدام TidTcPclient مباشرة.

إذا كنت ستستمر في استخدام TidTCPClient مباشرة، فعليك التوقف عن استخدام طريقة Tidiohandler.Alldata (). استخراج رأس الرد "طول المحتوى" (يمكنك التقاط () الرؤوس في قائمة Tstringlist أو قائمة TIDHEADER ثم استخدام قيمها [] خاصية [] (). سيساعد ذلك في ضمان عدم إيقاف قراءة I / O قراءة القراءة قبل الأوان بسبب قطع اتصال الخادم في نهاية الرد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top