Сокеты исторически открываются с использованием включенного алгоритма Нейгла , который задерживает небольшие пакеты в попытке оптимизировать сетевое взаимодействие.
При работе с небольшими пакетами следует установить сокет TCP_NODELAY
вариант.В Java вы можете сделать это, позвонив socket.setTcpNoDelay(true);
После настройки я получаю:
- 12000 пакетов / с без буфера
- 26000 пакетов /s с буфером
Мой скорректированный код:
public class Test {
static DataOutputStream cout(Socket s) throws IOException {
return new DataOutputStream( (s.getOutputStream()));
// return new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
}
static DataInputStream cin(Socket s) throws IOException {
return new DataInputStream( (s.getInputStream()));
}
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket server = new ServerSocket(12345);
new Thread(() -> {
try {
Thread.sleep(1000);
Socket client = new Socket("127.0.0.1", 12345);
client.setTcpNoDelay(true);
DataOutputStream out = cout(client);
DataInputStream in = cin(client);
long tm1 = System.currentTimeMillis();
int lastCount = 0;
for (int i=0;i<300000;i++) {
int a = in.readInt();
out.writeInt(a);
out.flush();
long tm2 = System.currentTimeMillis();
if ((tm2 - tm1) >= 1000) {
System.out.println(i - lastCount);
lastCount = i;
tm1 += 1000;
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}).start();
Socket client=server.accept();
client.setTcpNoDelay(true);
DataOutputStream out = cout(client);
DataInputStream in = cin(client);
for (int i=0;i<300000;i++){
out.writeInt(i);
out.flush();
if (i!=in.readInt()){
System.out.println("ERROR");
}
}
client.close();
server.close();
Thread.sleep(1000);
}
}