การเชื่อมต่อที่มีอยู่ถูกบังคับให้ปิดโดยโฮสต์ระยะไกล


159

ฉันกำลังทำงานกับแอพพลิเคชั่นทางการค้าที่ใช้ SocketException พร้อมข้อความ

การเชื่อมต่อที่มีอยู่ถูกบังคับให้ปิดโดยโฮสต์ระยะไกล

สิ่งนี้เกิดขึ้นกับการเชื่อมต่อซ็อกเก็ตระหว่างไคลเอนต์และเซิร์ฟเวอร์ การเชื่อมต่อยังมีชีวิตอยู่และดีและมีการถ่ายโอนข้อมูลจำนวนมาก แต่ก็จะถูกตัดการเชื่อมต่อออกจากที่ใดที่หนึ่ง

มีใครเห็นสิ่งนี้มาก่อนหรือไม่ สาเหตุอาจเกิดจากอะไร ฉันสามารถเดาสาเหตุบางอย่างได้ แต่ก็มีวิธีเพิ่มรหัสนี้ลงไปอีกไหมเพื่อหาสาเหตุที่เป็นไปได้

ความคิดเห็น / ความคิดใด ๆ ยินดีต้อนรับ

... ใหม่ล่าสุด ...

ฉันมีการบันทึกจากการติดตาม. NET บางรายการ

System.Net.Sockets Verbose: 0 : [8188] Socket#30180123::Send() DateTime=2010-04-07T20:49:48.6317500Z

System.Net.Sockets Error: 0 : [8188] Exception in the Socket#30180123::Send - An existing connection was forcibly closed by the remote host DateTime=2010-04-07T20:49:48.6317500Z 

System.Net.Sockets Verbose: 0 : [8188] Exiting Socket#30180123::Send() -> 0#0

จากส่วนอื่น ๆ ของการบันทึกฉันได้เห็นความจริงที่ระบุว่า '0 # 0' หมายถึงการส่งแพ็กเก็ตที่มีความยาว 0 ไบต์ แต่นั่นหมายความว่าอย่างไร

ความเป็นไปได้อย่างหนึ่งอย่างใดอย่างหนึ่งเกิดขึ้นและฉันไม่แน่ใจ

1) การเชื่อมต่อถูกปิด แต่ข้อมูลถูกเขียนลงในซ็อกเก็ตดังนั้นการสร้างข้อยกเว้นข้างต้น 0 # 0 นั้นหมายความว่าไม่มีสิ่งใดถูกส่งเนื่องจากซ็อกเก็ตปิดอยู่แล้ว

2) การเชื่อมต่อยังคงเปิดอยู่และแพ็คเก็ตของศูนย์ไบต์จะถูกส่ง (เช่นรหัสมีข้อผิดพลาด) และ 0 # 0 หมายความว่าแพ็คเก็ตของศูนย์ไบต์พยายามที่จะส่ง

คุณคิดยังไง มันอาจจะสรุปไม่ได้ว่าฉันเดา แต่บางทีคนอื่นเห็นสิ่งนี้?


เพียงแค่อัปเดต ดูเหมือนว่า wireshark จะไม่ตัดมันในกรณีนี้เนื่องจากการตั้งค่าเครือข่ายของเรา แต่ฉันหวังว่าจะลองสิ่งนี้blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspxซึ่งกำลังติดตามการใช้. NET ซึ่งควรสร้างไฟล์บันทึกบางไฟล์ ฉันจะให้คุณโพสต์ ...
— เตอร์

1
comcast เป็นที่รู้จักกันในการส่งแพ็คเก็ต "ศูนย์" ปลอมแปลงด้วย id ปลอมไปยุ่งกับปริมาณข้อมูล p2p ---

คำตอบ:


98

โดยทั่วไปหมายความว่าด้านระยะไกลปิดการเชื่อมต่อ (โดยปกติจะส่งRSTแพ็คเก็ตTCP / IP ) หากคุณกำลังทำงานกับแอปพลิเคชันบุคคลที่สามสาเหตุที่เป็นไปได้คือ:

  • คุณกำลังส่งข้อมูลที่มีรูปแบบไม่ถูกต้องไปยังแอปพลิเคชัน (ซึ่งอาจรวมถึงการส่งคำขอ HTTPS ไปยังเซิร์ฟเวอร์ HTTP)
  • ลิงก์เครือข่ายระหว่างไคลเอนต์และเซิร์ฟเวอร์กำลังปิดตัวลงด้วยเหตุผลบางประการ
  • คุณได้เรียกจุดบกพร่องในแอปพลิเคชันบุคคลที่สามที่ทำให้เกิดข้อผิดพลาด
  • แอปพลิเคชันบุคคลที่สามหมดทรัพยากรระบบ

เป็นไปได้ว่ากรณีแรกคือสิ่งที่เกิดขึ้น

คุณสามารถยิงWiresharkเพื่อดูว่าเกิดอะไรขึ้นบนเส้นลวดเพื่อ จำกัด ปัญหาให้แคบลง

หากไม่มีข้อมูลที่เฉพาะเจาะจงมากขึ้นมันไม่น่าเป็นไปได้ที่ทุกคนที่นี่จะสามารถช่วยเหลือคุณได้มาก


2
ยิ่งใหญ่ ขอบคุณ สิ่งอื่น ๆ เกี่ยวกับ wireshark มันรวบรวมข้อมูลมากมายฉันจะกรองบางอย่างเช่นนี้ได้อย่างไร หากการแสดง Wireshark บางสิ่งบางอย่างผมอาจจะโพสต์ไว้ที่นี่ในภายหลัง ...
— ปีเตอร์

4
คุณควรจะกรองการถ่ายโอนข้อมูล Wireshark ตามที่อยู่ IP และหมายเลขพอร์ตอย่างน้อยที่สุด หลังจากนั้นอาจเป็นประโยชน์มากที่สุดในการดูจุดสิ้นสุดของสตรีม (ซึ่งมีบางอย่างผิดปกติ) และทำงานย้อนกลับจนกว่าคุณจะสามารถมองเห็นจุดที่สิ่งต่าง ๆ เกิดขึ้นก่อน ทั้งนี้ขึ้นอยู่กับความซับซ้อนของโปรโตคอลที่เกี่ยวข้องก็สามารถเป็นเรื่องง่ายที่จะเป็นไปไม่ได้เกือบ ...
— RarrRarrRarr

4
มีแหล่งที่มาสำหรับรายการสัญลักษณ์แสดงหัวข้อย่อยหรือคำตอบของนักเล่นเกมด้านล่างเพียงแค่คัดลอกรายการของคุณ?
— Zack

7
โปรดทราบว่า "การส่งข้อมูลที่มีรูปแบบไม่ถูกต้อง" อาจหมายถึงการส่งhttpsคำขอไปยังhttpเซิร์ฟเวอร์และในทางกลับกัน
— AXMIM

2
ในกรณีของฉันฉันได้รับข้อยกเว้นนี้เฉพาะเมื่อเรียก api เมื่อเรียกใช้แอปในเครื่อง ไม่มีปัญหาในสภาพแวดล้อม dev, qa หรือ prod การแก้ไข? ใช้ http แทน https ภายในเครื่อง เราคิดว่าอาจเกี่ยวข้องกับโหลดบาลานเซอร์ แต่เราเพิ่งอัปเดต dev, qa และ prod web.configs ด้วยการแปลงสำหรับ https แก้ไขปัญหา.
— Kershaw

82

การใช้ TLS 1.2 แก้ไขข้อผิดพลาดนี้
คุณสามารถบังคับให้แอปพลิเคชันของคุณใช้ TLS 1.2 ด้วยสิ่งนี้ (ตรวจสอบให้แน่ใจว่าได้ดำเนินการก่อนที่จะเรียกใช้บริการของคุณ)

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

โซลูชันอื่น:
เปิดใช้งานการเข้ารหัสที่รัดกุมในเครื่องหรือเซิร์ฟเวอร์ของคุณเพื่อใช้ TLS1.2 เนื่องจากโดยค่าเริ่มต้นจะถูกปิดใช้งานดังนั้นจะใช้ TLS1.0 เท่านั้น
ในการเปิดใช้งานการเข้ารหัสที่รัดกุมดำเนินการ commande เหล่านี้ใน PowerShell ด้วยสิทธิ์ผู้ดูแลระบบ:

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

คุณต้องรีบูตคอมพิวเตอร์เพื่อให้การเปลี่ยนแปลงเหล่านี้มีผล


1
คุณสามารถเพิ่มค่าหลายค่าพร้อมกันเพื่อรองรับหลายโปรโตคอล ดังนั้นเพื่อรองรับทุกอย่างตั้งแต่ SSL3 ถึง TLS1.2 ให้ตั้งค่า SecurityProtocol = (SecurityProtocolType) 4080
— ลูกคิด

29

นี่ไม่ใช่ข้อผิดพลาดในรหัสของคุณ มันมาจากการใช้ Socket ของ. Net หากคุณใช้การใช้งานมากเกินไปของ EndReceive ด้านล่างคุณจะไม่ได้รับข้อยกเว้นนี้

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }

1
นี่มาจากระบบปฏิบัติการและในที่สุดก็มาจากเพื่อน จำเป็นต้องมีคำอธิบายเพิ่มเติมในข้อกล่าวหาว่าเป็นข้อบกพร่องของซอฟต์แวร์
— มาร์ควิสแห่ง Lorne

5
+1 ในโปรแกรม C # ของฉันฉันกำลังตีหัวของฉันเป็นสาเหตุที่EndReceiveทำให้เกิดข้อยกเว้นเมื่อมีการเลิกจ้างลูกค้าที่สง่างาม ไม่ทราบว่าเป็นเพราะการออกแบบ ฉันรู้สึกว่าการออกแบบไม่ดีในการจัดการข้อยกเว้นในโค้ดปกติ ขอบคุณพระเจ้าสำหรับวิธีที่มากเกินไป
— Pavan Manjunath

2
@MSaudi สิ่งนี้กำลังใช้การเรียกแบบอะซิงโครนัสให้แน่ใจว่าคุณเข้าใจรหัสของคุณจะไม่หยุดในขณะที่กำลังประมวลผลข้อมูลที่ส่งคืน ตัวอย่างการใช้msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx โดยทั่วไปคุณจะต้องมีStateObjectคลาสด้วยpublic byte[] buffer = new byte[1024], public Socket socket;และเรียกใช้ฟังก์ชันที่เรียกว่าReceive(Socket s)ซึ่งทำStateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); และในvoid ReceiveCallback(IAsyncResult ar)คุณเรียกรหัสนั้นข้างต้น
— vapcguy

2
@catatay ในขณะที่มันมีทางออกฉันไม่เคยเห็นคุณค่าในวิธีการแบบอะซิงโครนัสที่คุณจำเป็นต้องรู้ทันทีว่าสิ่งที่จะกลับมาหลังจากที่คุณทำของคุณSendก่อนที่คุณจะทำอะไรอย่างอื่น
— vapcguy

3
จริงๆแล้วฉันพบว่าวิธีนี้ไม่สามารถจะเข้าใจผิดได้ นอกจากนี้ยังสามารถทำให้เกิดข้อผิดพลาดของ OP: stackoverflow.com/questions/17790612/ …
— vapcguy

10

วิธีง่ายๆสำหรับปัญหาที่น่ารำคาญนี้:

เพียงไปที่ไฟล์ ".context.cs" (อยู่ใต้ " .context.tt" ซึ่งอยู่ใต้ไฟล์ "* .edmx" ของคุณ)

จากนั้นเพิ่มบรรทัดนี้ลงในตัวสร้างของคุณ:

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
    }

หวังว่านี่จะเป็นประโยชน์


@Esi จะวางที่ไหน และไม่มีประเภทผลตอบแทน?
— Khalil Khalaf

2
@FirstStep: เพราะนี่คือตัวสร้าง
— Nikhil Agrawal

3
สิ่งนี้จะช่วยให้ผู้ที่ใช้ Entity Framework ที่ประสบปัญหาไม่ใช่ผู้ที่กำลังทำการsocket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);อ่านไบต์ที่ส่งคืนซึ่งเป็นปัญหาของ OP อย่างง่าย
— vapcguy

ถ้าใช้ENTITY FRAMEWORKเฉพาะวิธีนี้ใช้งานได้ !!! แค่นี้ !
— Thanks

9

มีข้อผิดพลาดเดียวกัน ใช้งานได้จริงในกรณีที่ปริมาณการใช้ข้อมูลถูกส่งโดยใช้พร็อกซีบางส่วน (พู้ทำเล่นในกรณีของฉัน) อัปเดตกรอบงาน. NET จาก 4.5.2 เป็น> = 4.6 และตอนนี้ทุกอย่างทำงานได้ดี คำขอที่แท้จริงคือ:
new WebClient().DownloadData("URL");
ข้อยกเว้นคือ:

SocketException: การเชื่อมต่อที่มีอยู่ถูกบังคับให้ปิดโดยโฮสต์ระยะไกล


5
นี่เป็นวิธีหนึ่งในการแก้ปัญหาให้ฉัน จริง ๆ แล้วมันเกี่ยวข้องกับ TLS .NET เวอร์ชันที่ใช้โดยค่าเริ่มต้น 4.5.2 และ TLS ที่ใช้ต่ำกว่า 1.0 ในขณะที่ 4.6 และสูงกว่านั้นฉลาดกว่าเกี่ยวกับการอนุญาต 1.1 และ 1.2 สิ่งนี้สามารถพิสูจน์ได้ด้วยการวางข้อกำหนด TLS บนเซิร์ฟเวอร์ลงที่ 1.0 ซึ่งแก้ไขปัญหาเช่นกัน
— HotN

4

ฉันได้รับข้อยกเว้นนี้เนื่องจากการอ้างอิงแบบวงกลมในเอนทิตีในเอนทิตีที่มีลักษณะเหมือน

public class Catalog
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public Catalog Parent { get; set; }
    public ICollection<Catalog> ChildCatalogs { get; set; }
}

ฉันเพิ่ม [IgnoreDataMemberAttribute] ให้กับคุณสมบัติหลัก และนั่นก็แก้ปัญหาได้


2

ถ้าใช้บริการ A .Net 4.5.2

สำหรับฉันแล้วปัญหานี้เกิดขึ้นเนื่องจากการโทรทำงานในบริการ. Net 4.5.2 ฉันทำตามคำแนะนำ @willmaz แต่มีข้อผิดพลาดใหม่

ในการเรียกใช้บริการโดยเปิดการบันทึกฉันดูการจับมือกับไซต์เป้าหมายจะเริ่มต้นตกลง (และส่งโทเค็นผู้ถือ) แต่ในขั้นตอนต่อไปนี้เพื่อประมวลผลการโทรโพสต์ดูเหมือนว่าจะลดโทเค็นรับรองความถูกต้องแล้ว Unauthorizedตอบกลับด้วย

มันกลับกลายเป็นว่าข้อมูลประจำตัวของกลุ่มการบริการไม่มีสิทธิ์ในการเปลี่ยน TLS (?) และเมื่อฉันใส่บัญชีผู้ดูแลระบบภายในเครื่องของฉันลงในกลุ่มการทำงานทั้งหมดก็ใช้งานได้


2

สำหรับทุกคนที่ได้รับข้อยกเว้นนี้ในขณะที่อ่านข้อมูลจากสตรีมสิ่งนี้อาจช่วยได้ ฉันได้รับข้อยกเว้นนี้เมื่ออ่าน HttpResponseMessage ในลูปแบบนี้

using (var remoteStream = await response.Content.ReadAsStreamAsync())
using (var content = File.Create(DownloadPath))
{
    var buffer = new byte[1024];
    int read;

    while ((read = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await content.WriteAsync(buffer, 0, read);
        await content.FlushAsync();
    }
}

หลังจากระยะเวลาหนึ่งฉันพบผู้กระทำผิดคือขนาดบัฟเฟอร์ซึ่งเล็กเกินไปและเล่นได้ไม่ดีกับอินสแตนซ์ Azure ที่อ่อนแอของฉัน สิ่งที่ช่วยได้คือเปลี่ยนรหัสเป็น:

using (Stream remoteStream = await response.Content.ReadAsStreamAsync())
using (FileStream content = File.Create(DownloadPath))
{
    await remoteStream.CopyToAsync(content);
}

CopyTo ()วิธีการมีขนาดบัฟเฟอร์เริ่มต้นของ 81920 บัฟเฟอร์ที่ใหญ่กว่าเร่งกระบวนการและข้อผิดพลาดหยุดทันทีส่วนใหญ่เนื่องจากความเร็วในการดาวน์โหลดโดยรวมเพิ่มขึ้น แต่ทำไมความเร็วในการดาวน์โหลดถึงสำคัญในการป้องกันข้อผิดพลาดนี้?

อาจเป็นไปได้ว่าคุณถูกตัดการเชื่อมต่อจากเซิร์ฟเวอร์เนื่องจากความเร็วในการดาวน์โหลดลดลงต่ำกว่าเกณฑ์ขั้นต่ำที่เซิร์ฟเวอร์กำหนดไว้ให้อนุญาต ตัวอย่างเช่นในกรณีที่แอปพลิเคชันที่คุณดาวน์โหลดไฟล์ถูกโฮสต์อยู่บน IIS อาจเป็นปัญหากับการกำหนดค่า http.sys:

"Http.sys เป็นโพรโทคอล http โพรโทคอลที่ IIS ใช้เพื่อทำการสื่อสาร http กับไคลเอนต์มีตัวจับเวลาที่เรียกว่า MinBytesPerSecond ที่รับผิดชอบฆ่าการเชื่อมต่อถ้าอัตราการถ่ายโอนลดลงต่ำกว่าขีด จำกัด kb / วินาทีบางตัว ตั้งค่าเป็น 240 kb / วินาที "

ปัญหานี้ได้อธิบายไว้ใน blogpost เก่านี้จากทีมพัฒนา TFS และเกี่ยวข้องกับ IIS โดยเฉพาะ แต่อาจนำคุณไปในทิศทางที่ถูกต้อง นอกจากนี้ยังกล่าวถึงข้อบกพร่องเก่า ๆ ที่เกี่ยวข้องกับแอตทริบิวต์ http.sys นี้: ลิงก์

ในกรณีที่คุณใช้บริการแอป Azure และการเพิ่มขนาดบัฟเฟอร์ไม่ได้ช่วยขจัดปัญหาให้ลองปรับขนาดเครื่องของคุณด้วย คุณจะได้รับการจัดสรรทรัพยากรมากขึ้นรวมถึงแบนด์วิดธ์การเชื่อมต่อ


0

ฉันมีปัญหาเดียวกันและจัดการเพื่อแก้ไขในที่สุด ในกรณีของฉันพอร์ตที่ไคลเอนต์ส่งการร้องขอไปไม่มีใบรับรอง SSL ที่เชื่อมโยง ดังนั้นฉันจึงแก้ไขปัญหาโดยผูกใบรับรอง SSL กับพอร์ตที่ฝั่งเซิร์ฟเวอร์ เมื่อเสร็จแล้วข้อยกเว้นนี้ก็หายไป


-1

ข้อผิดพลาดนี้เกิดขึ้นในแอปพลิเคชันของฉันที่มีโปรโตคอล CIP เมื่อใดก็ตามที่ฉันไม่ได้ส่งหรือรับข้อมูลในเวลาน้อยกว่า 10 วินาที

นี่คือสาเหตุมาจากการใช้วิธีการเปิดไปข้างหน้า คุณสามารถหลีกเลี่ยงปัญหานี้ได้ด้วยการทำงานกับวิธีอื่นหรือติดตั้งอัตราการอัพเดทน้อยกว่า 10 วินาทีที่รักษาการเชื่อมต่อไปข้างหน้าของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.