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