gpt4 book ai didi

Java 和 Nagle 插图

转载 作者:可可西里 更新时间:2023-11-01 02:31:48 28 4
gpt4 key购买 nike

我试图在一个简单的客户端-服务器程序中说明 Nagle 算法。但我不太明白,也无法将其清楚地打印给我。

在我的示例中,客户端只是生成从 1 到 1024 的整数并将它们发送到服务器。服务器只是将这些 int 转换为十六进制字符串并将它们发送回客户端。

我所做的几乎所有更改都以相同的结果结束。 int 以 256 个 int 的 block 的形式发送和重新发送..我在两侧尝试了 setTcpNoDelay(true) 以查看更改,但这在我的控制台中给出了相同的结果。 (但不是在 wireshark 中,我发现服务器和客户端之间发送的数据包数量有很大差异)但我的目标是能够在控制台中看到它,我猜有一些 ObjectOutputStream 缓冲区或类似的东西可以支撑一切?

当我将 output = new PrintWriter(client.getOutputStream(), true) 更改为 false (truefalse:autoFlush - boolean 值;如果 true,则 printlnprintfformat 方法将刷新输出缓冲区)我的服务器不再将任何输出返回给客户端。

基本上,我的目标是在启动时将服务器和/或客户端的 true 或 false 作为参数来设置 TcpNoDelay,以便清楚地看到控制台中输入/输出的差异。我不确定所使用的所有内容,因此欢迎任何帮助来解决这个问题。

服务器:

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

客户端:

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

最佳答案

您将无法看到差异,因为 readLine() 将等待直到读取 eol。要查看差异,请使用二进制数据。使传出流写入由 10ms sleep 分隔的 64 字节 block 。使传入流读取 1024 字节的 block 。当 tcpNoDelay 为真时,传入流将在每次读取操作时读取大约 64 个字节。当 tcpNoDelay 为 false 时,传入流将读取更多字节。您可以记录每次读取操作读取的平均字节数,因此差异很明显。并且始终使用两台机器进行测试,因为操作系统可以优化环回流。

关于Java 和 Nagle 插图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2536768/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com