SORU
30 EYLÜL 2008, Salı


Neden imkansız, eş tarafından I/O, TCP soket incelikle kapalı olduğunu tespit etmek için çalışıyor.

Olarak takip etmek recent question merak ediyorum, neden bu imkansız Java olmadan çalışırken okuma/yazma üzerinde bir TCP soket, algılamak için yuva oldu incelikle kapalı olarak eş? Bu durumda bir kullanmasından bağımsız olarak pre-NİO Socket veya NİO SocketChannel gibi görünüyor.

Bir eş incelikle bir TCP bağlantısı kapandığında, bağlantı her iki tarafında TCP yığınları gerçeği biliyor. Sunucu tarafı (başlatan kapatma) biter devlet FIN_WAIT2, oysa istemci tarafı (tek o değil açıkça yanıt vermek için kapatma) biter devlet CLOSE_WAIT. Neden orada sorgulayabilen Socket SocketChannel yöntemi TCP temel TCP bağlantı sonlandırıldı olup olmadığını görmek için yığın değil mi? TCP yığını bu durumu sağlamayan bir bilgidir? Yoksa çekirdeğe pahalı bir çağrı önlemek için bir tasarım kararı mı?

Bu soruya zaten cevap attılar kullanıcıların yardımı ile, bu sorunu nasıl olacak, nereye doğru gittiğini görür gibiyim. Yanı yok açıkça yakın bağlantıyı biter TCP devlet CLOSE_WAIT anlamı bu bağlantı sürecinde kapatma ve bekler tarafı sorunu kendi CLOSE operasyon. Adil isConnected true isClosed döner bu kadar yeter sanırım döndürür false, ama neden orada isClosing gibi bir şey değil mi?

Aşağıda pre-NİO yuva kullanan test sınıfları. Ama aynı sonuçları kullanarak NİO elde edilir.

import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
  public static void main(String[] args) throws Exception {
    final ServerSocket ss = new ServerSocket(12345);
    final Socket cs = ss.accept();
    System.out.println("Accepted connection");
    Thread.sleep(5000);
    cs.close();
    System.out.println("Closed connection");
    ss.close();
    Thread.sleep(100000);
  }
}


import java.net.Socket;

public class MyClient {
  public static void main(String[] args) throws Exception {
    final Socket s = new Socket("localhost", 12345);
    for (int i = 0; i < 10; i  ) {
      System.out.println("connected: "   s.isConnected()   
        ", closed: "   s.isClosed());
      Thread.sleep(1000);
    }
    Thread.sleep(100000);
  }
}

Test test istemci sunucuya bağlandığında çıkış sunucu bağlantıyı kapatma başlatır sonra bile değişmeden kalır:

connected: true, closed: false
connected: true, closed: false
...

CEVAP
22 ŞUBAT 2012, ÇARŞAMBA


Ben kullanıyorum Yuva genellikle, çoğunlukla Seçiciler, ve olmasa da bir Ağ OSI uzman, anladığım, arama shutdownOutput() bir Yuva aslında gönderir bir şeyler ağı (FIN) uyanır benim Seçici öbür tarafta (aynı davranış C dili). Burada varalgılamaaslında bunu denediğimde başarısız olacak bir okuma işlemi tespit.

Zarif kopukluk yok ver kodu: kapanış giriş ve çıkış akışları hem de, kullanılabilecek veri okuma olanakları (bu nedenle onları kaybetme). Socket.close() Java yöntemi zarif kopukluk yapar inanmıyorum. C, Java ve şimdi yaptığım şey, düzgün bir Yuva diconnecting bu gibi yapılmalıdır:

  1. Kapatma soket çıkışı (gönderdiği diğer ucundaki FİN, bu şimdiye kadar bu yuva tarafından gönderilen son şeydir)
  2. Boş alan diğer ucunu (FİN algılar gibi, aynı zarif diconnection süreci boyunca devam edecek) cevap YÜZGECİ elimize kadar tampon. Bu aslında yuva arabellek hala veri içeren sürece kapatmıyor gibi bazı OS önemlidir. "Hayalet" OS tanımlayıcı numaraları ve soket kullanın (artık böyle bir sorun modern OS olmayabilir ;)) . " deniyor
  3. Yuva yakın

Aşağıdaki Java kod parçasında gösterildiği gibi

public void gracefulDisconnect(Socket sok) {
    InputStream is = sok.getInputStream();
    sok.shutdownOutput(); // Sends the 'FIN' on the network
    while (is.read() >= 0) ; // "read()" returns '-1' when the 'FIN' is reached
    sok.close(); // Now we can close the Socket
}

Tabii ki her iki taraf da aynı zarif kopukluk kullanmak ZORUNDA, ya da Gönderen kısmı daima while döngü meşgul tutmak için yeterli veri gönderiyor olabilir...

@WarrenDew işaret onun yorum atma, veri programı (uygulama katmanı) ikna olmayan zarif kesilmesi de uygulama katmanı: gerçi tüm veriler alındı TCP katmanı (while döngü), onlar atılır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Rockstar Games

    Rockstar Gam

    17 ŞUBAT 2006
  • Sergio Lafuente Rubio

    Sergio Lafue

    11 Aralık 2008
  • TheForgottenGamer1

    TheForgotten

    28 AĞUSTOS 2009