131 lines
3.5 KiB
Java
131 lines
3.5 KiB
Java
package biz.nellemann.jnetperf;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.io.*;
|
|
import java.net.*;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
public class TcpClient {
|
|
|
|
final Logger log = LoggerFactory.getLogger(TcpClient.class);
|
|
|
|
private final Statistics statistics;
|
|
|
|
private DataOutputStream out;
|
|
private DataInputStream in;
|
|
|
|
|
|
private final int port;
|
|
private final InetAddress address;
|
|
private Socket socket;
|
|
|
|
private final byte[] inBuffer = new byte[Payload.DEFAULT_LENGTH];
|
|
private final int packets;
|
|
private final int length;
|
|
private final int runtime;
|
|
|
|
|
|
public TcpClient(String hostname, int port, int length, int packets, int runtime) throws IOException {
|
|
log.info("TcpClient() - target: {}, port: {}", hostname, port);
|
|
|
|
this.port = port;
|
|
this.length = length;
|
|
this.packets = packets;
|
|
this.runtime = runtime;
|
|
|
|
address = InetAddress.getByName(hostname);
|
|
statistics = new Statistics();
|
|
}
|
|
|
|
|
|
private void send(Payload payload) throws IOException {
|
|
out.write(payload.getPayload());
|
|
statistics.transferPacket();
|
|
statistics.transferBytes(payload.getLength());
|
|
}
|
|
|
|
|
|
private Payload receive() throws IOException {
|
|
in.readFully(inBuffer);
|
|
return new Payload(inBuffer);
|
|
}
|
|
|
|
|
|
private void close() throws IOException {
|
|
in.close();
|
|
out.close();
|
|
socket.close();
|
|
}
|
|
|
|
|
|
public void start() throws IOException, InterruptedException {
|
|
|
|
AtomicBoolean keepRunning = new AtomicBoolean(true);
|
|
Thread shutdownHook = new Thread(() -> {
|
|
keepRunning.set(false);
|
|
System.out.println("Stopping jnetperf, please wait ...");
|
|
});
|
|
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
|
|
|
long sequence = 0;
|
|
socket = new Socket(address, port);
|
|
in = new DataInputStream(socket.getInputStream());
|
|
out = new DataOutputStream(socket.getOutputStream());
|
|
|
|
|
|
// Send handshake
|
|
Payload payload = new Payload(PayloadType.HANDSHAKE.getValue(), length, sequence++, packets);
|
|
send(payload);
|
|
payload = receive();
|
|
if(payload.getType() != PayloadType.ACK.getValue()) {
|
|
log.warn("No ACK!");
|
|
return;
|
|
}
|
|
|
|
// Send data
|
|
do {
|
|
payload = new Payload(PayloadType.DATA.getValue(), length, sequence++, packets);
|
|
send(payload);
|
|
payload = receive();
|
|
if(payload.getType() != PayloadType.ACK.getValue()) {
|
|
log.warn("No ACK!");
|
|
}
|
|
statistics.tick();
|
|
|
|
if (sequence > packets) {
|
|
System.out.println("Max packets reached");
|
|
keepRunning.set(false);;
|
|
}
|
|
|
|
if(runtime > 0 && statistics.getRuntime() > runtime) {
|
|
System.out.println("Max runtime reached");
|
|
keepRunning.set(false);
|
|
}
|
|
|
|
} while (keepRunning.get());
|
|
|
|
// Send end
|
|
payload = new Payload(PayloadType.END.getValue(), length, sequence++, packets);
|
|
send(payload);
|
|
payload = receive();
|
|
statistics.ack();
|
|
if(payload.getType() != PayloadType.ACK.getValue()) {
|
|
log.warn("No ACK!");
|
|
return;
|
|
}
|
|
|
|
Thread.sleep(100);
|
|
close();
|
|
statistics.printAverage();
|
|
statistics.printSummary();
|
|
}
|
|
|
|
|
|
public Statistics getStatistics() {
|
|
return statistics;
|
|
}
|
|
|
|
}
|