I am a beginner. Let me ask you questions with inadequate knowledge. Thank you.
In Java socket communication, I want to intentionally generate a delay due to the Nagle algorithm for study and operation check.
Currently 4 bytes are sent every 1 s from the client side, and the client side transmission time and server side transmission time are viewed on the console.
If i send a small amount of data, it will enter the Nagle buffer, and I think there will be a difference of about 200ms between the sending time and the receiving time, but there is almost no time difference now.
How does the Nagle algorithm cause delays?Please professor.
Applicable source codeServer side
public class Server {
public static ServerSocket ss = null;
public static Socket soc = null;
private static InputStream is = null;
private static OutputStream os = null;
public static void main (String [] args) {
try {
// create server socket
ss = new ServerSocket (5000);
soc = ss.accept ();
is = soc.getInputStream ();
Thread rcvTh = new ServerRcvThread (is);
rcvTh.start ();
// 10 seconds sleep
try {
Thread.sleep (10000);
} catch (Exception e) {
e.printStackTrace ();
}
// stop thread
rcvTh.stop ();
} catch (IOException e) {
e.printStackTrace ();
} finally {
try {
is.close ();
soc.close ();
ss.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
class ServerRcvThread extends Thread {
private static InputStream ins = null;
ServerRcvThread (InputStream is) {
this.ins = is;
}
public void run () {
DateFormat format = new SimpleDateFormat ("yyyy MM dd hh: mm: ss.SSS");
byte rcvData [] = new byte [16];
int size = 0;
try {
while (true) {
// Read data
size = ins.read (rcvData);
System.out.println ("size:" + size + "byte" + "Reception time =" + format.format (new Date ()));
}
} catch (IOException e) {
e.printStackTrace ();
}
}
}
Client side
public class Client {
private static Socket soc = null;
private static OutputStream os = null;
private static InputStream is = null;
public static void main (String [] args) {
try {
// socket generation
soc = new Socket ("127.0.0.1", 5000);
soc.setTcpNoDelay (false);// Explicitly turn on the Nagle algorithm
os = soc.getOutputStream ();
Thread sndTh = new ClientSndThread (os);
sndTh.start ();
// 10 seconds sleeptry {
Thread.sleep (10000);
} catch (Exception e) {
e.printStackTrace ();
}
// stop thread
sndTh.stop ();
} catch (IOException e) {
e.printStackTrace ();
} finally {
try {
is.close ();
os.close ();
soc.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
class ClientSndThread extends Thread {
private static OutputStream ous = null;
ClientSndThread (OutputStream os) {
this.ous = os;
}
public void run () {
DateFormat format = new SimpleDateFormat ("yyyy MM dd hh: mm: ss.SSS");
byte sndData [] = new byte [4];
sndData [0] = 0x04;
sndData [1] = 0x03;
sndData [2] = 0x02;
sndData [3] = 0x01;
try {
while (true) {
// write data
ous.write (sndData);
ous.flush ();
System.out.println ("Data transmission" + "Transmission time =" + format.format (new Date ()));
// 1 second sleep
try {
Thread.sleep (1000);
} catch (Exception e) {
e.printStackTrace ();
}
}
} catch (IOException e) {
e.printStackTrace ();
}
}
}
Code modification (11.22)
Server side
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Server
{
public static ServerSocket ss = null;
public static Socket soc = null;
private static InputStream is = null;
private static OutputStream os = null;
public static void main (String [] args)
{
try
{
// create server socket
ss = new ServerSocket (5000);
soc = ss.accept ();
soc.setTcpNoDelay (true);
is = soc.getInputStream ();
os = soc.getOutputStream ();
DateFormat format = new SimpleDateFormat ("yyyy MM dd hh: mm: ss.SSS");byte sndData [] = new byte [4];
sndData [0] = 0x01;
sndData [1] = 0x02;
sndData [2] = 0x03;
sndData [3] = 0x04;
while (true)
{
byte rcvData [] = new byte [16];
int size = 0;
// Read data (wait until received)
for (int tmp = 0;tmp<= 1;tmp ++)
{
size = is.read (rcvData);
System.out.println ("Data reception. Size:" + size + "byte. Transmission time =" + format.format (new Date ()));
if (size == 8)
{
break;
}
}
// The transmission from the client is delayed by 200ms. The response is also delayed by 200ms due to the ACK delay.
// Based on the above factors, the third and subsequent triggers
os.write (sndData);
os.flush ();
System.out.println ("Data transmission" + "Transmission time =" + format.format (new Date ()));
}
}
catch (IOException e)
{
e.printStackTrace ();
}
finally
{
try
{
is.close ();
os.close ();
soc.close ();
ss.close ();
}
catch (IOException e)
{
e.printStackTrace ();
}
}
}
}
Client side
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Client1 {
public static void main (String [] args) {
Thread client = new ClientThread ();
client.start ();
try {
//Thread.sleep(1000);
client.join ();
} catch (Exception e) {
e.printStackTrace ();
}
}
}
class ClientThread extends Thread {
private static Socket soc = null;
private static OutputStream os = null;
private static InputStream is = null;
public void run () {
try {
// socket generation
soc = new Socket ("172.23.56.83", 5000);
soc.setTcpNoDelay (false);
is = soc.getInputStream ();os = soc.getOutputStream ();
DateFormat format = new SimpleDateFormat ("yyyy MM dd hh: mm: ss.SSS");
byte sndData [] = new byte [4];
sndData [0] = 0x04;
sndData [1] = 0x03;
sndData [2] = 0x02;
sndData [3] = 0x01;
for (int cnt = 0;cnt<10;cnt ++) {
// First transmission (sent immediately)
os.write (sndData);
os.flush ();
System.out.println ("Data transmission" + "Transmission time =" + format.format (new Date ()));
// 0.01 second sleep
try {
Thread.sleep (10);
} catch (Exception e) {
e.printStackTrace ();
}
// 2nd transmission (1st ACK is delayed by 200ms due to delayed ACK)
// In addition, transmission by Nagle is also delayed by 200ms
os.write (sndData);
os.flush ();
System.out.println ("Data transmission" + "Transmission time =" + format.format (new Date ()));
byte rcvData [] = new byte [16];
int size = 0;
// Read data
size = is.read (rcvData);
System.out.println ("Data reception. Size:" + size + "byte. Transmission time =" + format.format (new Date ()));
}
} catch (UnknownHostException e1) {
e1.printStackTrace ();
} catch (IOException e1) {
e1.printStackTrace ();
} finally {
try {
is.close ();
os.close ();
soc.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
}
Result
When Nagle is on
Receive data. Size: 4byte. Send time = 2019 11 22 01: 05: 20.537
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 05: 20.584
Data transmission Transmission time = 2019 11 22 01: 05: 20.584
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 05: 20.584
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 05: 20.631
Data transmission Transmission time = 2019 11 22 01: 05: 20.631
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 05: 20.631
Receive data. Size: 4byte. Send time = 2019 11 22 01: 05: 20.678
Data transmission Transmission time = 2019 11 22 01: 05: 20.678
Receive data. Size: 4byte. Send time = 2019 11 22 01: 05: 20.678
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 05: 20.724
...
When Nagle is off
Receive data. Size: 8byte. Transmission time = 2019 11 22 01: 22: 21.897
Data transmission Transmission time = 2019 11 22 01: 22: 21.897
Receive data. Size: 4byte. Send time = 2019 11 22 01: 22: 21.900
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 22: 21.901
Data transmission Transmission time = 2019 11 22 01: 22: 21.901
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 22: 21.901
Receive data. Size: 4byte. Transmission time = 2019 11 22 01: 22: 21.917
Data transmission Transmission time = 2019 11 22 01: 22: 21.917
...
Environment
OS: win10
JDK: 1.8
IDE: eclipse
Server and client were on the same host.
-
Answer # 1
Related articles
- java - delayed execution does not work well in android studio (postdelayed error)
- algorithm when java is not uniquely determined by sword calculation
- algorithm for finding the number of squares with side 1 in a java circle
- java - algorithm for finding all enumerations of combinations
- java - [algorithm] i don't know why i %3 == 0 by the method to get the 1st, 4th, 7th, and 10th rows
- java - reverse polish notation algorithm can't be fixed normally
Simply. In socket communication that does not pass a communication line such as between the same host, the Nagle algorithm does not function because of the lower layer function than the application, so the communication line is passed.