Mevcut bir bağlantı uzak ana bilgisayar tarafından zorla kapatıldı


159

İletiyle bir SocketException özel durumu sunan ticari bir uygulama ile çalışıyorum,

Mevcut bir bağlantı uzak ana bilgisayar tarafından zorla kapatıldı

Bu, istemci ve sunucu arasındaki soket bağlantısı ile olur. Bağlantı canlı ve iyi ve yığın veri aktarılıyor, ancak daha sonra bağlantı kesiliyor.

Bunu daha önce gören var mı? Sebepler ne olabilir? Ben birkaç neden tahmin olabilir, ama aynı zamanda neden ne olabileceğini çözmek için bu koda daha fazla eklemek için herhangi bir yolu var mı?

Herhangi bir yorum / fikir bekliyoruz.

... En son ...

Bazı .NET izleme bazı günlük var,

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

Günlüğün diğer bölümlerine dayanarak '0 # 0' yazısının 0 bayt uzunluğunda bir paket gönderildiği anlamına geldiğini gördüm. Ama bu gerçekten ne anlama geliyor?

İki olasılıktan biri ortaya çıkıyor ve hangisinden emin değilim,

1) Bağlantı kapatılıyor, ancak veriler sokete yazılıyor, böylece yukarıdaki istisna yaratılıyor. 0 # 0, soket zaten kapalı olduğu için hiçbir şeyin gönderilmediği anlamına gelir.

2) Bağlantı hala açıktır ve sıfır baytlık bir paket gönderilmektedir (yani kodda bir hata vardır) ve 0 # 0, sıfır baytlık bir paketin gönderilmeye çalışıldığı anlamına gelir.

Ne düşünüyorsun? Sanırım sonuçsuz olabilir, ama belki başka biri böyle bir şey görmüş?


Sadece bir güncelleme. Ağ kurulumumuz nedeniyle wireshark'ın bu durumda kesmeyeceği anlaşılıyor. Ama umarım bunu deneyeceğim, bazı günlük dosyaları üretmesi gereken .NET kullanarak izleyen blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx . Seni haberdar edeceğim ...
peter

1
comcast da göndermek biliniyor "sıfır" paketler --- p2p trafik uğraşmak sahte kimlikli sahte

Yanıtlar:


98

Bu genellikle uzak tarafın bağlantıyı kapattığı anlamına gelir (genellikle bir TCP / IP RSTpaketi göndererek ). Üçüncü taraf bir uygulamayla çalışıyorsanız, olası nedenler:

  • Uygulamaya hatalı biçimlendirilmiş veriler gönderiyorsunuz (bir HTTP sunucusuna HTTPS isteği göndermeyi içerebilir)
  • İstemci ve sunucu arasındaki ağ bağlantısı bir nedenden dolayı kapanıyor
  • Üçüncü taraf uygulamasında kilitlenmesine neden olan bir hata tetiklediniz
  • Üçüncü taraf uygulaması sistem kaynaklarını tüketmiştir

Muhtemelen ilk vaka olan şeydir.

Sorunu daraltmak için telde ne olduğunu tam olarak görmek için Wireshark'ı ateşleyebilirsiniz .

Daha spesifik bilgi olmadan, buradaki herkesin size gerçekten çok yardımcı olabileceği olası değildir.


2
Harika. Teşekkürler. Wireshark hakkında başka bir şey. Çok fazla veri toplar, böyle bir şeyi nasıl filtreleyebilirim? Eğer wireshark bir şey gösterirse, daha sonra buraya gönderebilirim ...
peter

4
Wireshark dökümünü en azından IP adresine ve bağlantı noktası numarasına göre filtreleyebilmeniz gerekir. Bundan sonra, muhtemelen akışın sonuna (bir şeyler yanlış gittiğinde) bakmak ve işlerin ilk önce nerede dağıldığını görene kadar geriye doğru çalışmak en yararlıdır. İlgili protokolün karmaşıklığına bağlı olarak, neredeyse imkansız olmak gerçekten kolay olabilir ...
RarrRarrRarr

4
Madde işaretli öğeler için bir kaynak var mı veya aşağıdaki oyuncunun cevabı listenizi kopyaladı mı?
Zack

7
"Hatalı biçimlendirilmiş veri gönderme" httpsişleminin bir httpsunucuya istek göndermesi ve bunun tersi olabileceğini lütfen unutmayın .
AXMIM

2
Benim durumumda, bu uygulamayı yalnızca yerel olarak uygulama çalıştırırken bir API çağırırken alıyordum. Geliştirme, qa veya prod ortamlarında sorun yok. Çözüm? Yerel olarak https yerine http kullanılıyor. Bunun bir yük dengeleyici ile ilgili olabileceğini düşünüyoruz. Ancak dev, qa ve prod web.configs dosyamızı https dönüşümleriyle güncelledik. Sorun çözüldü.
Kershaw

82

TLS 1.2 kullanımı bu hatayı çözdü.
Uygulamanızı TLS 1.2 kullanarak zorlayabilirsiniz (hizmetinizi aramadan önce uyguladığınızdan emin olun):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Başka bir çözüm :
TLS1.2'yi kullanmak için yerel makinenizde veya sunucunuzda güçlü şifreleme özelliğini etkinleştirin, çünkü varsayılan olarak devre dışı bırakılmıştır, bu nedenle yalnızca TLS1.0 kullanılır.
Güçlü kriptografiyi etkinleştirmek için PowerShell'de şu komutları yönetici ayrıcalıklarıyla yürütü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 

Bu değişikliklerin geçerli olması için bilgisayarınızı yeniden başlatmanız gerekir.


1
Birden çok protokolü desteklemek için birlikte birden çok değer ekleyebilirsiniz. SSL3'ten TLS1.2'ye kadar her şeyi desteklemek için SecurityProtocol = (SecurityProtocolType) 4080'i ayarlayın.
Abaküs

29

Bu, kodunuzdaki bir hata değil. .Net'in Soket uygulamasından geliyor. EndReceive'ın aşırı yüklenmiş uygulamasını aşağıdaki gibi kullanırsanız, bu istisnayı alamazsınız.

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

1
Bu işletim sisteminden ve nihayetinde akrandan geliyor. Bir yazılım hatası olduğu iddiası hakkında daha fazla açıklama yapılması gerekmektedir.
Lorne Marquis

5
+1. C # programımda, EndReceivezarif bir istemci sonlandırması olduğunda neden bir istisna atıyor olarak kafamı vuruyordum. Bunun tasarım gereği olduğunu bilmiyordum. Normal kod akışlarında istisna atmak için kötü tasarım hissediyorum. Aşırı yüklenmiş yöntem için Tanrı'ya şükürler olsun.
Pavan Manjunath

2
@MSaudi Bu zaman uyumsuz bir çağrı kullanıyor, kodunuzun döndürülen verileri işlerken durmayacağını anladığınızdan emin olun. Örnek msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx kullanır . Temel olarak bir olması StateObjectile sınıf public byte[] buffer = new byte[1024], public Socket socket;ve adında bir işlevi çağırmak Receive(Socket s)yapar StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); ve void ReceiveCallback(IAsyncResult ar)üstünüzde, bu kodu arayın.
vapcguy

2
@cagatay Bir çözüm sunarken, Sendbaşka bir şey yapmadan önce ne yaptıktan sonra hemen geri döneceğinizi bilmeniz gereken asenkron yöntemlerde hiç değer görmedim .
vapcguy

3
Aslında bu yöntemin kusursuz olmadığını gördüm. Ayrıca OP'nin hatasına neden olabilir: stackoverflow.com/questions/17790612/…
vapcguy

10

Bu yaygın sinir bozucu sorun için basit bir çözüm:

Sadece " .context.cs" dosyanıza ( "* .edmx" dosyanızın altında bulunan " .context.tt" altında bulunur).

Ardından, bu satırı kurucunuza ekleyin:

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

umarım bu yardımcı olur.


@Esi bunu nereye koymalı? ve dönüş türü yok ??
Khalil Khalaf

2
@FirstStep: Çünkü bu bir kurucu.
Nikhil Agrawal

3
Bu, yalnızca sorun yaşayan Entity Framework kullananlara yardımcı olur socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);, OP'nin sorunu olan döndürülen baytları okumak için basit olanlara değil .
vapcguy

kullanıyorsanız ENTITY FRAMEWORKsadece bu çözüm çalışmalarını !!! sadece bu ! teşekkürler kardeşim :)
Rao Hammas

9

Aynı hata vardı. Aslında trafik bazı proxy (benim durumumda kemancı) kullanılarak gönderilmesi durumunda çalıştı. .NET çerçevesi 4.5.2'den> = 4.6'ya güncellendi ve şimdi her şey iyi çalışıyor. Asıl istek şuydu:
new WebClient().DownloadData("URL");
İstisna şuydu:

SocketException: Varolan bir bağlantı uzak ana bilgisayar tarafından zorla kapatıldı


5
Bu benim için işleri çözmenin bir yoluydu. Aslında, TLS .NET'in varsayılan olarak hangi sürümüyle kullanıldığıyla ilgiliydi. 4.5.2 ve altı TLS 1.0 kullanılırken, 4.6 ve üstü 1.1 ve 1.2'ye izin vermek konusunda daha akıllıdır. Bu, sunucudaki TLS gereksinimini de 1.0'a düşürerek sorunu çözdü.
HotN

4

Bu istisnayı varlıktaki dairesel referans nedeniyle aldım.

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

Üst özelliğe [IgnoreDataMemberAttribute] ekledim. Ve bu sorunu çözdü.


2

Bir .Net 4.5.2 Hizmetinde Çalışıyorsa

Benim için sorun bir .Net 4.5.2 hizmetinde çalıştığı için birleştirildi. @Willmaz önerisini takip ettim ama yeni bir hata aldım.

Günlüğe kaydetme açıkken hizmeti çalıştırırken, hedef site ile el sıkışmasının ok başlatacağını (ve taşıyıcı jetonunu göndereceğini) gördüm, ancak sonraki çağrıyı Post çağrısını işlemek için, kimlik doğrulama jetonunu bırakmış gibi görünüyor ve site ile cevap Unauthorized.

Hizmet havuzu kimlik bilgilerinin TLS (?) Değiştirme hakları olmadığı ortaya çıktı ve yerel yönetici hesabımı havuza koyduğumda hepsi işe yaradı.


2

Akıştan veri okurken bu istisnayı alan herkes için bu yardımcı olabilir. Ben böyle bir döngüde HttpResponseMessage okurken bu istisna alıyordum:

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

Bir süre sonra suçlunun, çok küçük olan ve zayıf Azure örneğimle iyi oynamamış arabellek boyutu olduğunu öğrendim. Yardımcı olan, kodu şu şekilde değiştirmekti:

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

Kopyala() yönteminin varsayılan arabellek boyutu 81920'dir. Daha büyük arabellek işlemi hızlandırdı ve büyük olasılıkla toplam indirme hızları arttığı için hatalar hemen durdu. Ancak indirme hızı neden bu hatayı önlemede önemlidir?

İndirme hızları sunucunun izin vermek üzere yapılandırıldığı minimum eşiğin altına düştüğü için sunucu ile bağlantınızı kesmeniz mümkündür. Örneğin, dosyayı indirdiğiniz uygulamanın IIS'de barındırılması durumunda, http.sys yapılandırmasında bir sorun olabilir:

"Http.sys, IIS'nin istemcilerle http iletişimi gerçekleştirmek için kullandığı http protokol yığınıdır. Aktarım hızı bir kb / sn eşiğinin altına düşerse bir bağlantıyı öldürmekten sorumlu MinBytesPerSecond adlı bir zamanlayıcı vardır. Varsayılan olarak, bu eşik 240 kb / sn'ye ayarlayın. "

Sorun, TFS geliştirme ekibinin bu eski blog yazısında açıklanmıştır ve özellikle IIS ile ilgilidir, ancak sizi doğru yönde gösterebilir. Ayrıca bu http.sys özniteliğiyle ilgili eski bir hatadan bahsediyor: link

Azure uygulama hizmetlerini kullanıyorsanız ve arabellek boyutunu artırmak sorunu ortadan kaldırmazsa, makinenizi de ölçeklendirmeye çalışın. Bağlantı bant genişliği de dahil olmak üzere size daha fazla kaynak tahsis edilecektir.


0

Aynı sorunu yaşadım ve sonunda çözmeyi başardım. Benim durumumda, istemcinin isteği gönderdiği bağlantı noktasının kendisine bir SSL sertifikası bağlaması yoktu. Bu yüzden, sunucu tarafındaki bağlantı noktasına bir SSL sertifikası bağlayarak sorunu çözdüm. Bu yapıldıktan sonra, bu istisna ortadan kalktı.


-1

Bu hata, 10 saniyeden daha az sürede veri göndermediğimde veya almadığım zaman CIP protokolü ile uygulamamda meydana geldi.

Bu, ileri açma yönteminin kullanılmasından kaynaklandı. Başka bir yöntemle çalışarak veya ileri-açık bağlantınızı koruyan 10'lardan daha düşük bir güncelleme oranı yükleyerek bunu önleyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.