it-swarm-tr.com

java.net.SocketException: Bağlantı sıfırlama

Bir soketten okumaya çalışırken aşağıdaki hatayı alıyorum. Bu InputStream üzerinde readInt() yapıyorum ve bu hatayı alıyorum. Belgelere bakıldığında bu, bağlantının istemci kısmının bağlantıyı kapattığını göstermektedir. Bu senaryoda, ben sunucuyum.

İstemci günlük dosyalarına erişimim var ve bağlantıyı kapatmıyor ve aslında günlük dosyaları bağlantıyı kapattığımı gösteriyor. Peki bunun neden olduğunu bilen var mı? Kontrol edilecek başka ne var? Bu, belki de eşik değerlere ulaşan yerel kaynaklar olduğunda ortaya çıkıyor mu?


Aşağıdaki satırda olduğumu unutmayın:

socket.setSoTimeout(10000);

readInt()'dan hemen önce. Bunun (uzun hikaye) bir nedeni var, ama sadece meraklı, bunun belirtilen hataya yol açabileceği durumlar var mı? Sunucuyu IDE'mde çalıştırıyorum ve IDE'ı bir kesme noktasında sıkıştırarak bıraktım ve ardından aynı hataları IDE'mdeki kendi günlüklerimde görünmeye başladığını fark ettim.

Her neyse, sadece söz, umarım kırmızı bir ringa balığı değil. :-(

109
Darryl

Bunun birkaç olası nedeni var.

  1. Diğer uç, bağlantıyı kasıtlı olarak, burada belgelenmeyecek şekilde sıfırladı. Uygulama yazılımının bunu yapması nadir ve genel olarak yanlıştır, ancak ticari yazılım için bilinmemektedir.

  2. Daha yaygın olarak, diğer ucun normal olarak kapatmış olduğu bir bağlantıya yazarak kaynaklanır. Başka bir deyişle, bir uygulama protokolü hatası.

  3. Soket alma arabelleğinde okunmamış veriler olduğunda bir soketi kapatmanın da nedeni olabilir.

  4. Windows'ta, 'bağlantı sıfırlama' ile aynı olmayan 'yazılım bağlantı iptaline neden oldu', sizin gönderdiğiniz ağ sorunlarından kaynaklanıyor. Bununla ilgili bir Microsoft bilgi tabanı makalesi var.

105
user207421

Bağlantı sıfırlama sadece bir TCP RST alındığı anlamına gelir. Bu, meslektaşınız işleyemediği verileri aldığında olur ve bunun çeşitli nedenleri olabilir.

En basit olanı soketi kapattığınızda çıktı akışına daha fazla veri yazmaktır. Soketi kapatarak, arkadaşınıza konuştuğunuzu söylediniz ve bu bağlantınızı unutabilir. Yine de bu akış hakkında daha fazla veri gönderdiğinizde, eş, dinlemediğini bilmeniz için bir RST ile reddeder.

Diğer durumlarda, araya giren bir güvenlik duvarı veya hatta uzak Ana Bilgisayarın kendisi TCP bağlantınızı "unutabilir". Bu, uzun süre hiçbir veri göndermezseniz (2 saat ortak bir zaman aşımıdır) veya eş yeniden başlatılıp etkin bağlantılar hakkındaki bilgilerini kaybettiğinden olabilir. Bu geçersiz bağlantılardan birine veri gönderme, RST'ye de neden olur.


Ek bilgilere yanıt olarak güncelleme:

SocketTimeoutException kullanımına yakından bakın. Bu istisna, bir soket işleminde engellenirken yapılandırılmış zaman aşımı aşılırsa ortaya çıkar. Bu istisna atıldığında soketin kendisinin durumu değişmez, ancak istisna işleyiciniz soketi kapatır ve ardından yazmaya çalışırsa, bağlantı sıfırlama durumunda olursunuz. setSoTimeout(), soketi başka bir ipliğin kapatması gibi kirli şeyler yapmadan sonsuza kadar engelleyebilecek bir read() işleminden kurtulmanız için size temiz bir yol sağlamak içindir.

43
erickson

Ne zaman böyle bir sorunla karşılaştığım zaman, genellikle WireShark gibi bir araçla oturuyorum ve ileri geri aktarılan ham verilere bakıyorum. İşlerin bağlantısının kesildiği yerlere şaşırmış olabilirsiniz ve yalnızca okumaya çalıştığınızda size bildirimde bulunulur .

13
GEOCHET

Söylemekten utanç verici olmakla birlikte, bu sorunu yaşadığımda, tüm verileri okumadan önce bağlantıyı kapatıyordum. Küçük dizelerin döndürüldüğü durumlarda, işe yaradı, ancak bu muhtemelen kapatmadan önce tüm yanıtın tamponlanmasından kaynaklanıyordu.

Daha uzun metin miktarlarının döndürülmesi durumunda, istisna atıldı, çünkü daha sonra bir arabellek geri geliyordu.

Bu gözetimi kontrol edebilirsin. Bir URL'yi açmanın bir dosya gibidir, tamamen okunduktan sonra kapattığınızdan (bağlantıyı bıraktığınızdan) emin olun.

8
Scott S

İzleri çok dikkatli incelemelisin,

Bir sunucu soket uygulamasına sahibim ve bir Java.net.SocketException: Connection reset vakasını düzelttim.

Benim durumumda, bir sebepten dolayı bağlantısı kesilen bir clientSocket Socket nesnesinden okunurken olur. (Şebeke kaybedildi, güvenlik duvarı veya uygulama çökmesi veya yakında olması bekleniyor)

Aslında bu Soket nesnesinden okurken bir hatayla karşılaştığımda bağlantıyı yeniden kuruyordum.

Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!

İlginç olan, for my Java Socket, eğer bir müşteri ServerSocket ile bağlantı kurarsa ve bağlantıyı hiçbir şey göndermeden kapatırsa is.read() kendisini özyinelemeli olarak çağırır. soket kapalı bir bağlantıdan okumaya çalışın. Okuma işlemi için aşağıdakine benzer bir şey kullanırsanız;

while(true)
{
  Receive();
}

Sonra bir yığın alırsınızTrace ve aşağıda gibi bir şey

Java.net.SocketException: Socket is closed
    at Java.net.ServerSocket.accept(ServerSocket.Java:494)

Yaptığım şey sadece ServerSocket’ı kapatmak ve bağlantımı yenilemek ve gelen müşteri bağlantılarını beklemek.

String Receive() throws Exception
{
try {                   
            int readed = is.read();
           ....
}catch(Exception e)
{
        tryReConnect();
        logit(); //etc
}


//...
}

Bu, bilinmeyen müşteri soketi kayıpları için bağlantımı yeniden kuruyor

private void tryReConnect()
        {
            try
            {
                ServerSocket.close();
                //empty my old lost connection and let it get by garbage col. immediately 
                clientSocket=null;
                System.gc();
                //Wait a new client Socket connection and address this to my local variable
                clientSocket= ServerSocket.accept(); // Waiting for another Connection
                System.out.println("Connection established...");
            }catch (Exception e) {
                String message="ReConnect not successful "+e.getMessage();
                logit();//etc...
            }
        }

Başka bir yol bulamadım çünkü görüntünün altından gördüğünüz gibi, bağlantının kopup kaybolmadığını try and catch olmadan anlayamazsınız, çünkü her şey doğru görünüyor. Bu anlık görüntüyü sürekli Connection reset elde ederken elde ettim.

enter image description here

8
Davut Gürbüz

Ben de aynı hatayı yaşadım. Şimdi problemin çözümünü buldum. Problem sunucu akışını okumadan önce müşteri programının bitmesiydi.

5
kml_ckr

Java ile yazılmış SOA sistemiyle bu sorunu yaşadım. Hem istemciyi hem de sunucuyu farklı fiziksel makinelerde çalıştırıyordum ve uzun süre boyunca iyi çalışıyorlardı, daha sonra bu kötü bağlantı sıfırlamaları istemci günlüğünde görünüyordu ve sunucu günlüğünde garip bir şey yoktu. Hem istemciyi hem de sunucuyu yeniden başlatmak sorunu çözmedi. Sonunda, sunucu tarafındaki yığının oldukça dolu olduğunu keşfettik, bu nedenle JVM için mevcut belleği arttırdık: sorun çözüldü! Kayıtta hiçbir OutOfMemoryError bulunmadığını unutmayın: bellek azdı, bitmedi.

4
Pino

Ayrıca, bir sunucuya SSH aracılığıyla komut göndermeye çalışan Java programında da bu sorunla karşılaştım. Sorun, makinenin Java kodunu çalıştırmasıydı. Uzak sunucuya bağlanmak için izne sahip değildi. Write () yöntemi iyi gidiyordu, ancak read () yöntemi bir Java.net.SocketException: Connection reset atıyordu. Bu sorunu, istemci SSH anahtarını bilinen uzaktaki anahtarlara eklemekle düzelttim.

1
pmartin8

Sunucunuzun Java sürümünü kontrol edin. Weblogic 10.3.6’m TLSv1’de olan 1.7.0_75 JDK’da olduğu için başıma geldi. Tüketmeye çalıştığım dinlenme noktası TLSv1.2'nin altındaki herhangi bir şeyi kapatıyordu.

Weblogic varsayılan olarak en güçlü paylaşılan protokolü müzakere etmeye çalışıyordu. Ayrıntılara bakınız: HTTPS bağlantıları için https.protocols System Property ayarını yapma ile ilgili sorunlar .

Desteklenen TLS'yi belirlemek için ayrıntılı SSL günlüğü ekledim. Bu, TLSv1'in el sıkışma için kullanıldığını gösterdi.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

Bu özelliği, JDK8 uyumlu ürünümüzün JDK8 varsayılanlarına TLSv1.2 olarak getirerek çözdüm. JDK7 ile sınırlı olanlar için, TLSv1.2'ye yükselterek Java 7 için bir geçici çözümü de başarıyla test ettim. Bu cevabı kullandım: Java 7'de TLS 1.2 nasıl etkinleştirilir

0
behold