org.apache.activemq.artemis.shaded.org.jgroups.tests.rt.transports.UdpTransport Maven / Gradle / Ivy
package org.apache.activemq.artemis.shaded.org.jgroups.tests.rt.transports;
import org.apache.activemq.artemis.shaded.org.jgroups.logging.Log;
import org.apache.activemq.artemis.shaded.org.jgroups.logging.LogFactory;
import org.apache.activemq.artemis.shaded.org.jgroups.tests.RoundTrip;
import org.apache.activemq.artemis.shaded.org.jgroups.tests.rt.RtReceiver;
import org.apache.activemq.artemis.shaded.org.jgroups.tests.rt.RtTransport;
import org.apache.activemq.artemis.shaded.org.jgroups.util.Util;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
/**
* Transport based on UDP datagrams. Note that this transport is not reliable: if a packet is dropped, the sender will
* wait for the response forever and this block.
* @author Bela Ban
* @since 4.0
*/
public class UdpTransport implements RtTransport {
protected DatagramSocket sock;
protected Receiver receiver_thread;
protected RtReceiver receiver;
protected InetAddress host;
protected int port=7800;
protected boolean server;
protected final Log log=LogFactory.getLog(UdpTransport.class);
protected List members=new ArrayList<>();
public UdpTransport() {
}
public String[] options() {
return new String[]{"-host ", "-port ", "-server"};
}
public void options(String... options) throws Exception {
if(options == null)
return;
for(int i=0; i < options.length; i++) {
if(options[i].equals("-server")) {
server=true;
continue;
}
if(options[i].equals("-host")) {
host=InetAddress.getByName(options[++i]);
continue;
}
if(options[i].equals("-port")) {
port=Integer.parseInt(options[++i]);
}
}
if(host == null)
host=InetAddress.getLocalHost();
}
public void receiver(RtReceiver receiver) {
this.receiver=receiver;
}
public Object localAddress() {return members != null? members.get(0) : null;}
public List clusterMembers() {
return members;
}
public void start(String ... options) throws Exception {
options(options);
if(server) { // simple single threaded server, can only handle a single connection at a time
sock=new DatagramSocket(port, host);
System.out.println("server started (ctrl-c to kill)");
receiver_thread=new Receiver();
receiver_thread.start();
}
else {
sock=new DatagramSocket();
members.add(sock.getLocalSocketAddress());
members.add(new InetSocketAddress(host, port));
receiver_thread=new Receiver();
receiver_thread.start();
}
}
public void stop() {
Util.close(sock);
}
public void send(Object dest, byte[] buf, int offset, int length) throws Exception {
DatagramPacket packet=new DatagramPacket(buf, offset, length, (SocketAddress)dest);
sock.send(packet);
}
protected class Receiver extends Thread {
public void run() {
byte[] buf=new byte[RoundTrip.PAYLOAD];
DatagramPacket packet=new DatagramPacket(buf, 0, buf.length);
for(;;) {
try {
sock.receive(packet);
if(packet.getLength() != RoundTrip.PAYLOAD)
throw new IllegalStateException("expected " + RoundTrip.PAYLOAD + " bytes, but got only " + packet.getLength());
if(receiver != null)
receiver.receive(packet.getSocketAddress(), buf, packet.getOffset(), packet.getLength());
}
catch(IOException ex) {
break;
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}
}