2010-09-13 28 views
24

Bir Java soket istemcisiyim. Sunucunun istemcime hala bağlı olduğu ancak iletime bir yanıt göndermediği bir durumda - sonunda bir zaman aşımı istisnası alıyorum.Bir soket nasıl hem bağlanabilir hem de kapatılabilir?

Bu durumda, soketimi yeniden bağlayıp kurmayacağımı veya yeniden kullanmaya devam edip etmeyeceğimi görmek için sınamak istiyorum.

böyle bir durumum kullanın:

if (!socket.isConnected() || socket.isClosed() || !socket.isBound()) { 
    try { 
     socket.close(); 
    } catch (IOException e1) { 
    } 
    // Wait on a new connection 
    socket = connectSocket(.....); 
} 

Ama hep yeniden görünmektedir. Ben Boole özelliklerin değerlerini oturum açtığınızda bu görüyorum:

bağlı: true kapalı: ciltli gerçek: true

nasıl bağlanıp kapatılabilir? TIA

+0

Yöntem çağrıları atomik değildir ... belki de başka bir iş parçacığı 'isConnected()' ve 'isClosed()' çağrıları arasındaki soketi mi kapatıyor? Belki önce soket nesnesinde senkronize etmek? – Powerlord

+0

Sadece isConnected() 've' isClosed() 'için denetimlerin sırasını tersine çevirdiğinizde bunu sınamak kolaydır. –

cevap

66

This thread

Bu konuyla ilgili bazı yararlı tartışmalar vardır. Socket.isConnected'un (hiç) başarılı bir şekilde bağlanmış olması durumunda doğru olarak döndüğü ortaya çıkıyor. Yukarıdaki dizisinden

:

Eğer gözardı görünüyor Socket(), kullanmak

, Socket.isConnected() Socket.connect() veya çağrılmış olup olmadığını söyler. Benzer şekilde isClosed() ve close() için. Bu yöntemlere göre

karışıklık protokolü kontrolü altındadır genel bağlantı, durumuna ile, bir uygulamanın kontrolü altında olan soket, durumunu kafa kaynaklanır. isConnected() ve isClosed() sokete ne yaptığınızı anlatır. bağlantısının durumunu belirlemek için okuma ve yazma dışında bir API yoktur.

docs diyor ki:

İade gerçek soket başarıyla bir sunucuya bağlı olmadığını

değil biri olarak belki de "döner doğru beklenebilir soket bağlıysa bir sunucuya ".

davranış Soket kaynağı bakarak teyit edilebilir:

Socket s = new Socket(); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: "  + s.isBound() + 
        " isClosed: " + s.isClosed()); 

s.connect(new InetSocketAddress("google.com", 80)); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: " + s.isBound() + 
        " isClosed: " + s.isClosed()); 

s.close(); 

System.out.println("isConnected: " + s.isConnected() + 
        " isBound: " + s.isBound() + 
        " isClosed: " + s.isClosed()); 

yazdırır:

isConnected: false isBound: false isClosed: false 
isConnected: true isBound: true isClosed: false 
isConnected: true isBound: true isClosed: true 

public boolean isConnected() { 
    // Before 1.3 Sockets were always connected during creation 
    return connected || oldImpl; 
} 

Ayrıca bu küçük testi pasajını çalıştırabilir Bu noktada belgelerin oldukça belirsiz olduğunu söylemeliyim ve yöntem ismi biraz m yönetiyor.

+11

+1 Bravo! Mükemmel cevap! –

+2

Teşekkürler. Şimdi bana açık. – sproketboy

+0

Kırık link, ancak alıntılar dan ya burdan ya da Sun/Oracle Java Forum, birçoğu tarafından bana cevaplardan holus-bolus kaldırılmış gibi görünüyor. – EJP

İlgili konular