الحصول على "اتصال أساسي" على httpwebrequest
-
29-09-2019 - |
سؤال
لدي تطبيق مكتوب في vb.net (ليس ASP.NET ، إنه تطبيق وحدة تحكم Windows). أحاول الاتصال بعنوان URL (صفحة HTML) واستعادة الاستجابة في سلسلة. الاستجابة مستقيمة JSON ، لا علامات HTML على الإطلاق. يفتح مع {
ويغلق مع }
.
أقوم بإنشاء كائن httpwebrequest غرامة. ثم اتصل req.GetResponse()
. بمجرد أن أفعل هذا ، أحصل على الخطأ The underlying connection was closed: The connection was closed unexpectedly.
لقد كنت googling والتحقق من stackoverflow ، وجربت كل ما وجدته ينطبق (الكثير منها يتعلق بتكوينات خدمة WCF ، والتي لا تنطبق).
ها هو رمزتي:
Public Function GetJSON(ByRef d As db.Device) As Boolean
Try
d.Url = "http://" & d.IpAddress & ini.doc.<svc>.<url>.Value
Dim req As HttpWebRequest = HttpWebRequest.Create(d.Url)
// req.Accept = "*/*"
// req.Timeout = 30000
// req.ReadWriteTimeout = 30000
// req.KeepAlive = False
// req.UseDefaultCredentials = True
// req.CachePolicy = HttpWebRequest.DefaultCachePolicy
// req.Proxy = HttpWebRequest.DefaultWebProxy
// req.ProtocolVersion = New System.Version(1, 0)
Dim rsp As HttpWebResponse = req.GetResponse()
Return True
Catch ex As Exception
Log(ex.Message)
Return False
Finally
rsp = Nothing
req = Nothing
End Try
End Function
الخطوط التي تم التعليق عليها (نمط التعليق الخاطئ ، ولكن لذلك سوف يتم تحليلها بشكل صحيح) هي كل الأشياء التي جربتها حتى الآن بناءً على ما وجدته عبر الإنترنت. لا أحد منهم إصلاحه. لقد تحقق من أن عنوان URL الذي يتم بناؤه صحيح ؛ إذا اتصلت بعنوان URL نفسه بالضبط في متصفحي ، فإنه يعيد الاستجابة المتوقعة المناسبة تمامًا.
لقد جربت Wiresharking It ... وأرى البيانات الكاملة المتوقعة الفعلية التي تعود إلى خرج القرش ، ثم بضعة أسطر ، ثم خط أحمر يقول:http > 51943 [RST] Seq=1607 Win=0 Len=0
وهو السطر الأخير الذي يظهر قبل .NET هو رمي الخطأ.
حاولت أيضًا تشغيل System.Net
تتبع/تسجيل لكل منشور هنا على ذلك ، وفي ملف الإخراج من ذلك ، أرى بالمثل جميع بيانات JSON المتوقعة يفعل عد ، ولكن بعد أن عادت ، يلقي هذه الخطوط في سجل تتبع .NET:
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 1605#1605
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Receive()
System.Net.Sockets Verbose: 0 : [7040] Data from Socket#60467532::Receive
System.Net.Sockets Verbose: 0 : [7040] 00000000 : :
System.Net.Sockets Verbose: 0 : [7040] Exiting Socket#60467532::Receive() -> 0#0
System.Net.Sockets Verbose: 0 : [7040] Socket#60467532::Dispose()
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816:: - The underlying connection was closed: The connection was closed unexpectedly.
System.Net Error: 0 : [7040] Exception in the HttpWebRequest#27806816::GetResponse - The underlying connection was closed: The connection was closed unexpectedly.
أي أفكار إلى أين تذهب بجانب محاولة اكتشاف هذا؟ نحن نقرأ هذه البيانات من بعض أجهزة استشعار المراقبة البيئية ، وقد أعطونا هذا عنوان URL هذا للاستخدام.
شيئان يحصلان علي حقًا ويربكني في هذا الأمر هما ذلك
أ) فهو يعمل بشكل جيد تمامًا عند استدعاء المتصفح
ب) يظهر كل من Wireshark و .net تتبع جميع البيانات بالفعل هو العودة ، والإطار هو لسبب ما باستثناء بعد تلقي جميع البيانات!
إن WebException بحد ذاته هو استخدام ضئيل للغاية ، حيث أن innerexception هو فارغ وحالتها تقول فقط "ConnectionClosed {8}"
شكرا مقدما!!!
تحديث 08/18 1130: لقد حاولت الآن استخدام فقط System.Net.WebRequest
في مقابل HttpWebRequest
. هذا لم يحدث أي فرق أيضا.
تحديث 08/18 1222: لقد حاولت فقط تبديل الكود الخاص بي بدلاً من استخدام [Http]Web[Request|Response]
لتخفيف أ WebClient
الكائن بدلاً من ذلك واستخدامه DownloadString()
طريقة. هذا ومع ذلك ايضا يلقي نفس الخطأ الدقيق.
تحديث 08/18 1230: حاول استخدام My.Computer.Network.DownloadFile()
- يحصل أيضًا على نفس الخطأ المغلقة.
المحلول
هل يمكنك نشر محتويات Trace Log بالكامل على Pastebin.com ونشر رابط هنا؟
قد تحصل على هذا الاستثناء لأن الخادم قد يقول في رأس "طول المحتوى" أنه يرسل بايت من الكيان ، لكنه في الواقع يرسل أقل من بايت N ويغلق الاتصال.
إجابه:
شكرا للبيانات. من تتبع Tracelog و Wireshark ، يبدو أن الخادم لا يرسل أي رؤوس استجابة ، وإرسال البيانات مباشرة. هذا هو انتهاك بروتوكول HTTP. هذا هو السبب في أن العميل يرمي الاستثناء.
نصائح أخرى
إليكم كيف جعلتها تعمل ... بفضل Feroze لتوجيهها لي في الاتجاه الصحيح!
(منحت النقاط)
Public Function GetJSON(ByRef d As db.Device) As Boolean
Try
Dim tcp = New TcpClient()
tcp.Connect(d.IpAddress, 80)
Dim ns = tcp.GetStream()
Dim req As Byte() = System.Text.Encoding.ASCII.GetBytes(
"GET /getdata.htm HTTP/1.1" & vbCrLf & vbCrLf
)
ns.Write(req, 0, req.Length)
Dim rsp(2048) As Byte, rcv As Integer
Do
rcv = ns.Read(rsp, 0, rsp.Length)
d.JSON &= System.Text.Encoding.ASCII.GetString(rsp, 0, rcv)
Loop Until rcv = 0
tcp.Close()
Return True
Catch ex As Exception
Log(ex.Message)
Return False
End Try
End Function
هذا يساعدني. آمل أن يساعد شخص ما أيضًا.
مباشرة بعد إنشاء كائن httpwebrequest ، أضف هذا السطر.
System.Net.ServicePointManager.SecurityProtocol = System.net.SecurityProtocoltype.ssl3 ؛
ما يعنيه هو تحديد طبقة المقبس الآمنة (SSL) 3.0 كبروتوكول أمان
تحقق من الكمون من الطلب. إذا كان أكثر من بضعة MS ، فهذا يستحق تعطيل خوارزمية Nagle
ServicePointManager.UseNagleAlgorithm = false;
كنت أواجه نفس المشكلة فيما يتعلق بطلب بدون هيئة. في حالتي ، قم بتعيين ملف ContentLength
إلى صفر إصلاح المشكلة.
في حالتي ، كانت المشكلة استخدمنا "http: // .." كعنوان خدمة بدلاً من "https: //" ...