J'essaie d'illustrer l'algorithme de Nagle dans un programme simple client-serveur. Mais je n'arrive pas à le comprendre ou à l'imprimer clairement.Illustration de Java et Nagle
Dans mon exemple, le client génère simplement des int de 1 à 1024 et les envoie au serveur. Le serveur convertit simplement ces int en une chaîne hexadécimale et les renvoie au client.
À peu près tout ce que je change finit avec les mêmes résultats. Les int sont envoyés et renvoyés dans des blocs de 256 int. J'ai essayé setTcpNoDelay (true) des deux côtés pour voir un changement mais cela donne le même résultat dans ma console. (mais pas dans wireshark, je vois une grande différence dans la quantité de paquets envoyés entre le serveur et le client) Mais mon but est de pouvoir le voir dans la console, je suppose qu'il y a du buffer d'ObjectOutputStream ou similaire en haut?
Quand je change output = new PrintWriter(client.getOutputStream(), true)
-false
(Le true
ou false
: autoFlush
- Valeur booléenne, si true
, les println
, printf
ou format
méthodes videra le tampon de sortie) mon serveur ne donne pas de sortie de retour à la client plus. Fondamentalement mon but est juste de donner vrai ou faux avec le serveur et/ou le client comme argument pour régler le TcpNoDelay, quand il est démarré, pour voir clairement la différence d'entrée/sortie dans la console. Je ne suis pas sûr de tout ce qui est utilisé, donc toute aide pour l'éclaircir est la bienvenue.
Le serveur:
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");
}
}
}
Le client:
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();
}
}
}
Vous pouvez tester avec un pair juste l'envoi et un autre juste la réception et la journalisation. Mais selon votre exemple, je comprends que vous voulez un voyage du serveur à des fins d'analyse comparative. Dans ce cas, laissez votre serveur avec tcpNoDelay toujours allumé et faites-lui lire un bloc de 4096 octets et répondez rapidement avec le nombre d'octets qu'il vient de lire. Vous verrez la différence en variant simplement tcpNoDelay sur le client. – fernacolo