2010-03-29 11 views
6

Basit bir istemci-sunucu programında Nagle algoritmasını göstermeye çalışıyorum. Ama bunu tam olarak anlayamıyorum ya da bana açıkça basılmasını sağlayamam. Benim örnekteJava ve Nagle illustration

, istemci sadece 1024 1'den int 's üretir ve sunucuya bu gönderir. Sunucu sadece bu int'yi bir hex dizesine dönüştürür ve bunları istemciye geri gönderir.

Değiştirdiğim her şey aynı sonuçlarla biter. Int, 256 int'nin blokları içinde gönderilir ve yeniden gönderilir .. Değişiklik görmek için her iki tarafa setTcpNoDelay (true) denedim ancak bu aynı sonucu konsolumda verir. (ama wireshark'ta değil, sunucu ve istemci arasında gönderilen paketlerin miktarında büyük bir fark görüyorum) Ama amacım konsolda görebilmek, sanırım ObjectOutputStream veya benzeri her şeyi tutan bir tampon var. yukarı? benim sunucu geri herhangi bir çıktı vermez; -: (true eğer println, printf veya format yöntemleri çıkış arabelleği canına okuyacak bir boolean autoFlushtrue veya false) Ben output = new PrintWriter(client.getOutputStream(), true)-falsedeğiştirmek

artık müşteri.

Temel olarak amacım, sunucuya ve/veya istemciye bir argüman olarak doğru ya da yanlış verilmesidir. TcpNoDelay, başlatıldığında, konsoldaki giriş/çıkış farkını net olarak görmek için. Ben her şeyden emin değilim, bu yüzden bunu temizlemek için herhangi bir yardım edilir.

sunucusu:

package Networks.Nagle; 

import java.io.*; 
import java.net.*; 
import java.util.*; 

public class NagleDemoServer 
{ 
    private static ServerSocket serverSocket; 
    private static final int PORT = 1234; 

    public static void main(String[] args) throws IOException 
    { 
     int received = 0; 
     String returned; 
     ObjectInputStream input = null; 
     PrintWriter output = null; 
     Socket client; 

     try 
     { 
      serverSocket = new ServerSocket(PORT); 
      System.out.println("\nServer started..."); 
     } 
     catch (IOException ioEx) 
     { 
      System.out.println("\nUnable to set up port!"); 
      System.exit(1); 
     } 

     while(true) 
     { 
      client = serverSocket.accept(); 
      client.setTcpNoDelay(true); 

      System.out.println("\nNew client accepted.\n"); 

      try 
      { 
       input = new ObjectInputStream(client.getInputStream()); 
       output = new PrintWriter(client.getOutputStream(), true); 

       while(true) 
       { 
        received = input.readInt(); 
        returned = Integer.toHexString(received); 
        System.out.print(" " + received); 
        output.println(returned.toUpperCase()); 

       } 
      } 
      catch(EOFException eofEx) 
      { 
       output.flush(); 
       System.out.println("\nEnd of client data.\n"); 
      } 
      catch(SocketException sEx) 
      { 
       System.out.println("\nAbnormal end of client data.\n"); 
      } 
      catch(IOException ioEx) 
      { 
       ioEx.printStackTrace(); 
      } 

      input.close(); 
      output.close(); 
      client.close(); 
      System.out.println("\nClient closed.\n"); 
     } 
    } 
} 

istemcisi: Bir eol okunana kadar

package Networks.Nagle; 

import java.io.*; 
import java.net.*; 
import java.util.*; 

public class NagleDemoClient 
{ 
    private static InetAddress host; 
    private static final int PORT = 1234; 

    public static void main(String[] args) 
    { 
     Socket socket = null; 

     try 
     { 
      host = InetAddress.getByName("localhost"); 

      socket = new Socket(host, PORT); 

      socket.setTcpNoDelay(true); 
      socket.setSendBufferSize(64); 

      System.out.println("Send Buffer: " + socket.getSendBufferSize()); 
      System.out.println("Timeout: " + socket.getSoTimeout()); 
      System.out.println("Nagle deactivated: " + socket.getTcpNoDelay()); 

     } 
     catch(UnknownHostException uhEx) 
     { 
      System.out.println("\nHost ID not found!\n"); 
      System.exit(1); 
     } 
     catch(SocketException sEx) 
     { 
      sEx.printStackTrace(); 
     } 
     catch(IOException ioEx) 
     { 
      ioEx.printStackTrace(); 
     } 

     NagleClientThread client = new NagleClientThread(socket); 
     NagleReceiverThread receiver = new NagleReceiverThread(socket); 

     client.start(); 
     receiver.start(); 

     try 
     { 
      client.join(); 
      receiver.join(); 

      socket.close(); 
     } 
     catch(InterruptedException iEx) 
     { 
      iEx.printStackTrace(); 
     } 
     catch(IOException ioEx) 
     { 
      ioEx.printStackTrace(); 
     } 

     System.out.println("\nClient finished."); 
    } 
} 


class NagleClientThread extends Thread 
{ 
    private Socket socket; 

    public NagleClientThread(Socket s) 
    { 
     socket = s; 

    } 

    public void run() 
    { 
     try 
     { 
      ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); 

      for(int i = 1; i < 1025; i++) 
      { 
       output.writeInt(i); 
       sleep(10); 
      } 

      output.flush(); 
      sleep(1000); 
      output.close(); 
     } 
     catch(IOException ioEx) 
     { 
      ioEx.printStackTrace(); 
     } 
     catch(InterruptedException iEx) 
     { 
      iEx.printStackTrace(); 
     } 
    } 
} 


class NagleReceiverThread extends Thread 
{ 
    private Socket socket; 

    public NagleReceiverThread(Socket s) 
    { 
     socket = s; 
    } 

    public void run() 
    { 
     String response = null; 
     BufferedReader input = null; 

     try 
     { 
      input = new BufferedReader(
         new InputStreamReader(socket.getInputStream())); 

      try 
      { 
       while(true) 
       { 
        response = input.readLine(); 
        System.out.print(response + " "); 
       } 
      } 
      catch(Exception e) 
      { 
       System.out.println("\nEnd of server data.\n"); 
      }  

      input.close(); 

     } 
     catch(IOException ioEx) 
     { 
      ioEx.printStackTrace(); 
     } 
    } 
} 

cevap

0

Sen taleb çünkü farkı (görmek mümkün olmayacaktır) bekleyecektir. Farkı görmek için ikili verileri kullanın. Çıkış akışını, 10 ms uyku ile ayrılmış 64 baytlık bloklar yapın. Gelen akışın 1024 baytlık blokları okumasını sağlayın. TcpNoDelay doğru olduğunda, gelen akış her okuma işleminde yaklaşık 64 bayt okunur. TcpNoDelay yanlış olduğunda, gelen akış çok daha fazla bayt okuyacaktır. Her bir okuma işleminde okunan ortalama bayt sayısını kaydedebilirsiniz, böylece fark açıktır. Ayrıca, her zaman iki makine kullanarak test edin, çünkü işletim sistemi geri döngü akışlarını optimize edebilir.

+0

Sadece gönderen ve sadece alma ve giriş yapma gibi bir eş ile test edebilirsiniz. Ancak örneğinize göre, karşılaştırma amaçlı bir sunucu gezisi istediğinizi anlıyorum. Bu durumda, sunucunuzu tcpNoDelay ile her zaman açık bırakın ve 4096 baytlık bir bloğu okumasını sağlayın ve hemen okuduğu her bir sayıdaki baytla hemen yanıt verin. Sadece müşteri üzerinde tcpNoDelay'ı değiştirerek farkı göreceksiniz. – fernacolo