2010-03-29 14 views
6

Próbuję zilustrować algorytm Walkera w prostym programie klient-serwer. Ale nie jestem w stanie tego dokładnie rozgryźć, czy też wyraźnie go wydrukować.Ilustracja Java i Nagle

W moim przykładzie klient po prostu generuje int od 1 do 1024 i wysyła je na serwer. Serwer po prostu konwertuje te int na ciąg szesnastkowy i odsyła je do klienta.

Niemal wszystko, co zmieniam, kończy się z tymi samymi wynikami. Int są wysyłane i wysyłane ponownie w blokach 256 int .. Próbowałem setTcpNoDelay (true) po obu stronach, aby zobaczyć zmianę, ale daje to ten sam wynik w mojej konsoli. (ale nie w wireshark, widzę dużą różnicę w ilości pakietów wysyłanych między serwerem a klientem). Ale moim celem jest możliwość zobaczenia go w konsoli, zgaduję, że jest jakiś bufor ObjectOutputStream lub podobny, trzymający wszystko w górę?

Kiedy zmienić output = new PrintWriter(client.getOutputStream(), true) do false(The true lub false: autoFlush - Boolean; jeśli true, że println, printf lub format metody będzie opróżnić bufor wyjściowy) mój serwer nie daje żadnego wyjścia z powrotem do klient już.

Zasadniczo moim celem jest podanie wartości true lub false z serwerem i/lub klientem jako argumentem, aby ustawić TcpNoDelay, po uruchomieniu, aby wyraźnie zobaczyć różnicę w danych wejściowych/wyjściowych w konsoli. Nie jestem pewien co do wszystkiego, więc każda pomoc, aby to wyjaśnić, jest mile widziana.

Serwer:

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

Klient:

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

Odpowiedz

0

nie będzie mógł dostrzec różnicę ponieważ readline() będzie czekać aż do EOL jest odczytywany. Aby zobaczyć różnicę, użyj danych binarnych. Utwórz wychodzące strumienie bloków zapisu o długości 64 bajtów oddzielone od 10 ms. Niech strumień wejściowy odczyta bloki o wielkości 1024 bajty. Kiedy tcpNoDelay ma wartość true, strumień przychodzący będzie odczytywany około 64 bajtów przy każdej operacji odczytu. Kiedy tcpNoDelay ma wartość false, strumień przychodzący odczyta znacznie więcej bajtów. Możesz zarejestrować średnią liczbę bajtów odczytanych w każdej operacji odczytu, więc różnica jest oczywista. A także zawsze testuj używając dwóch maszyn, ponieważ system operacyjny może zoptymalizować strumienie zwrotne.

+0

Możesz testować z jednym wysłanym równorzędnym i drugim po prostu odbierając i rejestrując. Ale na podstawie Twojego przykładu, rozumiem, że chcesz wyruszyć na serwer do testów porównawczych. W takim przypadku niech twój serwer z tcpNoDelay będzie zawsze włączony i sprawi, że będzie czytał blok 4096 bajtów i szybko odpowie na każdą liczbę bajtów, które właśnie przeczytał. Zobaczysz różnicę, zmieniając po prostu tcpNoDelay na kliencie. – fernacolo

Powiązane problemy