jnetperf/src/main/java/biz/nellemann/jnetperf/TcpClient.java

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