Một kết nối hiện có đã bị đóng bởi máy chủ từ xa


158

Tôi đang làm việc với một ứng dụng thương mại đang gửi một SocketException với thông báo,

Một kết nối hiện có đã bị đóng bởi máy chủ từ xa

Điều này xảy ra với một kết nối ổ cắm giữa máy khách và máy chủ. Kết nối vẫn còn sống và tốt, và hàng đống dữ liệu đang được truyền đi, nhưng sau đó nó bị ngắt kết nối.

Có ai nhìn thấy điều này trước đây? Nguyên nhân có thể là gì? Tôi có thể đoán một vài nguyên nhân, nhưng cũng có cách nào để thêm nhiều hơn vào mã này để tìm ra nguyên nhân có thể là gì không?

Bất kỳ ý kiến ​​/ ý tưởng đều được chào đón.

... Mới nhất ...

Tôi có một số đăng nhập từ một số dấu vết .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

Dựa trên các phần khác của việc ghi nhật ký, tôi đã thấy thực tế là nó nói '0 # 0' có nghĩa là một gói có độ dài 0 byte đang được gửi. Nhưng điều đó thực sự có ý nghĩa gì?

Một trong hai khả năng đang xảy ra, và tôi không chắc đó là gì

1) Kết nối đang được đóng, nhưng dữ liệu sau đó được ghi vào ổ cắm, do đó tạo ra ngoại lệ ở trên. 0 # 0 đơn giản có nghĩa là không có gì được gửi vì ổ cắm đã bị đóng.

2) Kết nối vẫn mở và một gói byte không được gửi (tức là mã có lỗi) và 0 # 0 có nghĩa là một gói byte không đang cố gắng được gửi.

Bạn nghĩ gì? Tôi đoán nó có thể không thuyết phục, nhưng có lẽ ai đó đã nhìn thấy loại điều này?


Chỉ là một bản cập nhật. Có vẻ như wireshark sẽ không cắt nó trong trường hợp này vì thiết lập mạng của chúng tôi. Nhưng tôi hy vọng sẽ thử điều này, blog.msdn.com/dgorti/archive/2005/09/18/471003.aspx đang truy tìm bằng .NET sẽ tạo ra một số tệp nhật ký. Tôi sẽ giữ cho bạn được đăng ...
peter

1
comcast cũng được biết là gửi các gói "không" giả mạo với id giả để gây rối với lưu lượng p2p ---

Câu trả lời:


98

Điều này thường có nghĩa là phía từ xa đã đóng kết nối (thường bằng cách gửi RSTgói TCP / IP ). Nếu bạn đang làm việc với ứng dụng của bên thứ ba, các nguyên nhân có thể là:

  • Bạn đang gửi dữ liệu không đúng định dạng đến ứng dụng (có thể bao gồm gửi yêu cầu HTTPS đến máy chủ HTTP)
  • Liên kết mạng giữa máy khách và máy chủ bị hỏng vì một số lý do
  • Bạn đã kích hoạt một lỗi trong ứng dụng của bên thứ ba khiến nó bị sập
  • Ứng dụng của bên thứ ba đã cạn kiệt tài nguyên hệ thống

Có khả năng trường hợp đầu tiên là những gì đang xảy ra.

Bạn có thể kích hoạt Wireshark để xem chính xác những gì đang xảy ra trên dây để thu hẹp vấn đề.

Nếu không có thông tin cụ thể hơn, chắc chắn không ai ở đây có thể thực sự giúp bạn nhiều.


2
Tuyệt quá. Cảm ơn. Những điều khác về wireshark. Nó thu thập rất nhiều dữ liệu, làm thế nào tôi có thể lọc ra một cái gì đó như thế này? Nếu wireshark xuất hiện một cái gì đó tôi có thể đăng nó ở đây sau này ...
peter

4
Bạn ít nhất có thể lọc kết xuất Wireshark theo địa chỉ IP và số cổng. Sau đó, có lẽ hữu ích nhất là nhìn vào cuối luồng (nơi có sự cố xảy ra) và làm việc ngược lại cho đến khi bạn có thể nhận ra nơi mọi thứ đầu tiên bị rối tung. Tùy thuộc vào độ phức tạp của giao thức liên quan, nó có thể thực sự dễ đến mức gần như không thể ...
RarrRarrRarr

4
Có nguồn nào cho các mục có dấu đầu dòng không, hoặc câu trả lời của người chơi dưới đây chỉ sao chép danh sách của bạn?
Zack

7
Xin lưu ý rằng "gửi dữ liệu không đúng định dạng" có thể có nghĩa là gửi httpsyêu cầu đến httpmáy chủ và có thể ngược lại.
AXMIM

2
Trong trường hợp của tôi, tôi chỉ nhận được ngoại lệ này khi gọi api khi chạy ứng dụng cục bộ. Không có vấn đề trong môi trường dev, qa hoặc prod. Cách khắc phục? Sử dụng http thay vì https cục bộ. Chúng tôi nghĩ rằng nó có thể liên quan đến một bộ cân bằng tải. Nhưng chúng tôi vừa cập nhật dev, qa và prod web.configs của chúng tôi với các biến đổi cho https. Vấn đề được giải quyết.
Kershaw

82

Sử dụng TLS 1.2 đã giải quyết lỗi này.
Bạn có thể buộc ứng dụng của mình sử dụng TLS 1.2 bằng cách này (đảm bảo thực thi nó trước khi gọi dịch vụ của bạn):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Một giải pháp khác:
Kích hoạt mã hóa mạnh trong máy hoặc máy chủ cục bộ của bạn để sử dụng TLS1.2 vì theo mặc định, nó bị vô hiệu hóa nên chỉ sử dụng TLS1.0.
Để kích hoạt mã hóa mạnh, hãy thực thi các lệnh này trong PowerShell với quyền quản trị viên:

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 

Bạn cần khởi động lại máy tính để những thay đổi này có hiệu lực.


1
Bạn có thể thêm nhiều giá trị với nhau để hỗ trợ nhiều giao thức. Vì vậy, để hỗ trợ mọi thứ từ SSL3 đến TLS1.2, hãy đặt SecurityProtocol = (SecurityProtocolType) 4080.
Bàn tính

29

Đây không phải là một lỗi trong mã của bạn. Nó đến từ việc triển khai socket của .Net. Nếu bạn sử dụng triển khai EndReceive quá tải như dưới đây, bạn sẽ không gặp ngoại lệ này.

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

1
Điều này đến từ hệ điều hành, và cuối cùng là từ các đồng nghiệp. Giải thích thêm là cần thiết cho cáo buộc rằng đó là một lỗi phần mềm.
Hầu tước Lorne

5
+1. Trong chương trình C # của tôi, tôi đã đập đầu vào lý do tại sao lại EndReceiveném một ngoại lệ khi có một chấm dứt khách hàng duyên dáng. Không biết đây là do thiết kế. Tôi cảm thấy thiết kế xấu của nó để ném ngoại lệ trong dòng mã bình thường. Cảm ơn Chúa vì phương pháp quá tải.
Pavan Manjunath

2
@MSaudi Đây là sử dụng một cuộc gọi không đồng bộ, hãy chắc chắn rằng bạn hiểu mã của mình sẽ không dừng lại trong khi nó đang xử lý dữ liệu được trả về. Ví dụ sử dụng msdn.microsoft.com/en-us/l Library / bew39x2a (v = vs.110) .aspx . Về cơ bản bạn phải có mộtStateObject lớp với public byte[] buffer = new byte[1024], public Socket socket;và gọi một hàm được gọi Receive(Socket s), hàm này StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); và trong đó void ReceiveCallback(IAsyncResult ar)bạn gọi mã đó ở trên.
vapcguy

2
@cagatay Mặc dù nó cung cấp một giải pháp, tôi chưa bao giờ thấy giá trị trong các phương thức không đồng bộ nơi bạn cần biết ngay điều gì sẽ quay trở lại sau khi bạn làm Sendtrước khi bạn có thể làm bất cứ điều gì khác.
vapcguy

3
Thật ra tôi thấy rằng phương pháp này không thể đánh lừa được. Nó cũng có thể gây ra lỗi của OP: stackoverflow.com/questions/17790612/ trên
vapcguy

10

Giải pháp đơn giản cho vấn đề gây phiền nhiễu phổ biến này:

Chỉ cần truy cập tệp ".context.cs " của bạn (nằm dưới " .context.tt" nằm dưới tệp "* .edmx" của bạn).

Sau đó, thêm dòng này vào hàm tạo của bạn:

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

hy vọng điều này là hữu ích.


@Esi đặt cái này ở đâu? và không có loại trả lại ??
Khalil Khalaf

2
@FirstStep: Vì đây là một nhà xây dựng.
Nikhil Agrawal

3
Điều này chỉ giúp những người sử dụng Entity Framework đang gặp sự cố, không phải những người đang làm đơn giản socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);để đọc các byte được trả về, đó là vấn đề của OP.
vapcguy

nếu ENTITY FRAMEWORKchỉ sử dụng giải pháp này hoạt động !!! chỉ cái này cảm ơn bạn :)
Rao Hammas

9

Có lỗi tương tự. Trên thực tế đã hoạt động trong trường hợp lưu lượng được gửi bằng một số proxy (fiddler trong trường hợp của tôi). Đã cập nhật .NET framework từ 4.5.2 đến> = 4.6 và bây giờ mọi thứ đều hoạt động tốt. Yêu cầu thực tế là:
new WebClient().DownloadData("URL");
Ngoại lệ là:

SocketException: Một kết nối hiện có đã bị đóng bởi máy chủ từ xa


5
Đây là một cách để giải quyết mọi thứ cho tôi. Nó thực sự có liên quan đến phiên bản TLS .NET được sử dụng theo mặc định. 4.5.2 và TLS 1.0 được sử dụng thấp hơn, trong khi 4.6 trở lên thông minh hơn về việc cho phép 1.1 và 1.2. Điều này cũng có thể chứng minh được bằng cách giảm yêu cầu TLS trên máy chủ xuống 1.0, điều này cũng đã khắc phục vấn đề này.
HotN

4

Tôi đã có ngoại lệ này vì tham chiếu vòng tròn trong thực thể. Trong thực thể trông giống như

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

Tôi đã thêm [IgnoreDataMemberAttribution] vào thuộc tính Parent. Và điều đó đã giải quyết vấn đề.


2

Nếu đang chạy trong dịch vụ .Net 4.5.2

Đối với tôi, sự cố đã được giải quyết do cuộc gọi đang chạy trong dịch vụ .Net 4.5.2. Tôi đã làm theo đề xuất @willmaz nhưng gặp lỗi mới.

Khi chạy dịch vụ với tính năng đăng nhập được bật, tôi đã xem việc bắt tay với trang đích sẽ bắt đầu ok (và gửi mã thông báo mang theo) nhưng ở bước sau để xử lý cuộc gọi Post, nó dường như sẽ bỏ mã xác thực auth và trang web sẽ giảm trả lời với Unauthorized.

Hóa ra thông tin đăng nhập nhóm dịch vụ không có quyền thay đổi TLS (?) Và khi tôi đưa tài khoản quản trị viên cục bộ của mình vào nhóm, tất cả đều hoạt động.


2

Đối với bất kỳ ai nhận được ngoại lệ này trong khi đọc dữ liệu từ luồng, điều này có thể giúp ích. Tôi đã nhận được ngoại lệ này khi đọc httpResponseMessage trong một vòng lặp như thế này:

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();
    }
}

Sau một thời gian, tôi phát hiện ra thủ phạm là kích thước bộ đệm, quá nhỏ và không chơi tốt với thể hiện Azure yếu của tôi. Điều đã giúp là thay đổi mã thành:

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

Sao chép ()Phương thức có kích thước bộ đệm mặc định là 81920. Bộ đệm lớn hơn đã tăng tốc quá trình và các lỗi đã dừng ngay lập tức, rất có thể là do tốc độ tải xuống chung tăng lên. Nhưng tại sao tải xuống vấn đề tốc độ trong việc ngăn chặn lỗi này?

Có thể bạn bị ngắt kết nối với máy chủ vì tốc độ tải xuống dưới ngưỡng tối thiểu mà máy chủ được cấu hình để cho phép. Ví dụ: trong trường hợp ứng dụng bạn đang tải xuống tệp được lưu trữ trên IIS, thì đó có thể là một vấn đề với cấu hình http.sys:

"Http.sys là ngăn xếp giao thức http mà IIS sử dụng để thực hiện giao tiếp http với khách hàng. Nó có bộ đếm thời gian gọi là MinBytesPerSecond chịu trách nhiệm hủy kết nối nếu tốc độ truyền của nó giảm xuống dưới ngưỡng kb / giây. Theo mặc định, ngưỡng đó là đặt thành 240 kb / giây. "

Vấn đề được mô tả trong blogpost cũ này từ nhóm phát triển TFS và đặc biệt liên quan đến IIS, nhưng có thể chỉ cho bạn một hướng đi đúng đắn. Nó cũng đề cập đến một lỗi cũ liên quan đến thuộc tính http.sys này: link

Trong trường hợp bạn đang sử dụng các dịch vụ ứng dụng Azure và việc tăng kích thước bộ đệm không loại bỏ được sự cố, hãy thử mở rộng quy mô máy của bạn. Bạn sẽ được phân bổ nhiều tài nguyên hơn bao gồm cả băng thông kết nối.


0

Tôi đã có cùng một vấn đề và quản lý để giải quyết nó cuối cùng. Trong trường hợp của tôi, cổng mà khách hàng gửi yêu cầu không có chứng chỉ SSL ràng buộc với nó. Vì vậy, tôi đã khắc phục sự cố bằng cách ràng buộc chứng chỉ SSL với cổng ở phía máy chủ. Một khi điều đó đã được thực hiện, ngoại lệ này đã biến mất.


-1

Lỗi này xảy ra trong ứng dụng của tôi với giao thức CIP bất cứ khi nào tôi không gửi hoặc nhận dữ liệu trong vòng chưa đến 10 giây.

Điều này được gây ra bởi việc sử dụng phương pháp mở về phía trước. Bạn có thể tránh điều này bằng cách làm việc với một phương pháp khác hoặc để cài đặt tốc độ cập nhật ít hơn 10 giây duy trì kết nối mở về phía trước của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.