socketclient - tcp cliente java
IlustraciĆ³n de Java y Nagle (1)
Estoy tratando de ilustrar el algoritmo de Nagle en un programa simple de cliente-servidor. Pero no puedo entenderlo, o hacer que me lo impriman claramente.
En mi ejemplo, el cliente simplemente genera int de 1 a 1024 y los envía al servidor. El servidor solo convierte estos int a una cadena hexadecimal y los envía de vuelta al cliente.
Casi todo lo que cambio termina con los mismos resultados. Los int se envían y se vuelven a enviar en bloques de 256 int. Probé setTcpNoDelay (verdadero) en ambos lados para ver un cambio, pero esto da el mismo resultado en mi consola. (pero no en wireshark, veo una gran diferencia en la cantidad de paquetes enviados entre el servidor y el cliente). Pero mi objetivo es poder verlo en la consola, supongo que hay algún buffer de ObjectOutputStream o algo similar que contenga todo ?
Cuando cambio output = new PrintWriter(client.getOutputStream(), true)
a false
( true
o false
: autoFlush
- A boolean; si es true
, los println
, printf
o format
println
el búfer de salida) mi servidor no lo hace devolver cualquier salida al cliente.
Básicamente mi objetivo es dar verdadero o falso con el servidor y / o el cliente como argumento para configurar el TcpNoDelay, cuando se inicia, para ver claramente la diferencia en la entrada / salida en la consola. No estoy seguro de todo lo que se usó, así que cualquier ayuda para aclarar esto es bienvenida.
El servidor:
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");
}
}
}
El cliente:
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();
}
}
}
No podrá ver la diferencia porque readLine () esperará hasta que se lea una eol. Para ver la diferencia, usa datos binarios. Haga que la secuencia saliente escriba bloques de 64 bytes separados por 10ms duerme. Haga que la secuencia entrante lea bloques de 1024 bytes. Cuando tcpNoDelay es verdadero, la secuencia entrante se leerá aproximadamente en 64 bytes en cada operación de lectura. Cuando tcpNoDelay es falso, la secuencia entrante leerá muchos más bytes. Puede registrar el número promedio de bytes leídos en cada operación de lectura, por lo que la diferencia es obvia. Y también pruebe siempre utilizando dos máquinas, porque el sistema operativo puede optimizar las transmisiones en bucle invertido.