Last active
December 19, 2020 14:54
-
-
Save kimathie/e601db10169c2f0ebd00c9b401366a52 to your computer and use it in GitHub Desktop.
A socket client utility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.net.DatagramPacket; | |
import java.net.DatagramSocket; | |
import java.net.InetSocketAddress; | |
import java.net.Socket; | |
import java.net.SocketException; | |
import java.net.SocketTimeoutException; | |
import java.nio.ByteBuffer; | |
/** | |
* A Socket client utility. | |
* | |
* @author kimathie | |
*/ | |
public abstract class SocketUtil { | |
/** | |
* Writes a stream of byte to a TCP channel. | |
* | |
* @param address a host address and port number pair. | |
* @param data a byte array with information. | |
* @throws java.io.IOException | |
* @throws io.cardinal.exception.MembershipException | |
*/ | |
public static void tcp(InetSocketAddress address, byte[] data) throws IOException { | |
Send.tcp(address.getHostString(), address.getPort(), data); | |
} | |
/** | |
* Writes a stream of byte to a TCP channel. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @throws java.io.IOException | |
* @throws io.cardinal.exception.MembershipException | |
*/ | |
public static void tcp(String host, int port, byte[] data) throws IOException { | |
try (Socket socket = new Socket();) { | |
socket.setTcpNoDelay(true); | |
socket.connect(new InetSocketAddress(host, port), 2000); | |
//write to socket | |
OutputStream out = socket.getOutputStream(); | |
out.write(data); | |
} | |
} | |
/** | |
* Writes a stream of byte to a TCP channel and blocks waiting for a | |
* response. | |
* | |
* @param address a host address and port number pair. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] tcpblock(InetSocketAddress address, byte[] data) throws IOException, SocketTimeoutException { | |
return Send.tcpblock(address.getHostString(), address.getPort(), data); | |
} | |
/** | |
* Writes a stream of byte to a TCP channel and blocks waiting for a | |
* response. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] tcpblock(String host, int port, byte[] data) throws IOException, SocketTimeoutException { | |
return Send.tcpblock(host, port, data, 0); | |
} | |
/** | |
* Writes a stream of byte to a TCP channel and blocks waiting for a | |
* response. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] tcpblock(String host, int port, byte[] data, long readTimeout) throws IOException, SocketTimeoutException { | |
return Send.tcpblock(host, port, data, 0, readTimeout); | |
} | |
/** | |
* Writes a stream of byte to a TCP channel and blocks waiting for a | |
* response. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] tcpblock(String host, int port, byte[] data, long connectTimeout, long readTimeout) throws IOException, SocketTimeoutException { | |
try (Socket socket = new Socket();) { | |
socket.setReceiveBufferSize(1024 * 8); | |
socket.setSoTimeout((int) readTimeout); | |
socket.setTcpNoDelay(true); | |
socket.connect(new InetSocketAddress(host, port), (int) connectTimeout); | |
//write to socket | |
OutputStream out = socket.getOutputStream(); | |
out.write(data); | |
//read from socket | |
ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 8); | |
InputStream in = socket.getInputStream(); | |
while (true) { | |
int b = in.read(); | |
buffer.put((byte) b); | |
int available = in.available(); | |
if (available <= 0) { | |
break; | |
} | |
} | |
byte[] reply = new byte[buffer.position()]; | |
buffer.flip(); | |
buffer.get(reply, 0, reply.length); | |
return reply; | |
} | |
} | |
/** | |
* Writes a stream of byte to a UDP socket. | |
* | |
* @param address a host address and port number pair. | |
* @param data a byte array with information. | |
* @throws java.io.IOException | |
* @throws io.cardinal.exception.MembershipException | |
*/ | |
public static void udp(InetSocketAddress address, byte[] data) throws IOException { | |
Send.udp(address.getHostString(), address.getPort(), data); | |
} | |
/** | |
* Writes a stream of byte to a UDP socket. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @throws java.io.IOException | |
* @throws io.cardinal.exception.MembershipException | |
*/ | |
public static void udp(String host, int port, byte[] data) throws IOException { | |
InetSocketAddress address = new InetSocketAddress(host, port); | |
try (DatagramSocket socket = new DatagramSocket();) { | |
DatagramPacket request = new DatagramPacket(data, data.length, address); | |
socket.send(request); | |
} | |
} | |
/** | |
* Writes a stream of byte to a UDP channel and blocks waiting for a | |
* response. | |
* | |
* @param address a host address and port number pair. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] udpblock(InetSocketAddress address, byte[] data) throws IOException, SocketException { | |
return Send.udpblock(address.getHostString(), address.getPort(), data); | |
} | |
/** | |
* Writes a stream of byte to a UDP channel and blocks waiting for a | |
* response. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] udpblock(String host, int port, byte[] data) throws IOException, SocketException { | |
return Send.udpblock(host, port, data, 0); | |
} | |
/** | |
* | |
* Writes a stream of byte to a UDP channel and blocks waiting for a | |
* response. | |
* | |
* @param host A string representation of the physical address of a | |
* node[machine] in a network. | |
* @param port An integer representation of the communication endpoint of a | |
* node[machine] in a network. | |
* @param data a byte array with information. | |
* @param readTimeout | |
* @return an object with information. | |
* @throws io.cardinal.exception.MembershipException | |
* @throws java.net.SocketTimeoutException | |
*/ | |
public static byte[] udpblock(String host, int port, byte[] data, long readTimeout) throws IOException, SocketException { | |
InetSocketAddress address = new InetSocketAddress(host, port); | |
try (DatagramSocket socket = new DatagramSocket();) { | |
socket.setSoTimeout((int) readTimeout); | |
//Write to datagrm socket | |
DatagramPacket request = new DatagramPacket(data, data.length, address); | |
socket.send(request); | |
//Read from datagram socket. | |
byte[] buffer = new byte[1024 * 8]; | |
DatagramPacket received = new DatagramPacket(buffer, buffer.length, address); | |
socket.receive(received); | |
byte[] reply = new byte[received.getLength()]; | |
System.arraycopy(received.getData(), 0, reply, 0, reply.length); | |
return reply; | |
} | |
} | |
public static void main(String[] args) throws InterruptedException { | |
int max = 20; | |
int portion = max / 2; | |
boolean runUdp = true; | |
CountDownLatch latch = new CountDownLatch(max); | |
if (runUdp) { | |
for (int b = 0; b < portion; b++) { | |
String prefix = "Reply[" + b + "]: "; | |
byte[] data = ("UDP Request from Sender [" + b + "]").getBytes(); | |
Thread udp = new Thread(() -> { | |
try { | |
byte[] reply = Send.udpblock("127.0.0.1", 8191, data); | |
System.out.println(prefix + new String(reply)); | |
} catch (SocketException e) { | |
System.err.println(e); | |
} catch (IOException e) { | |
System.err.println(e); | |
} finally { | |
latch.countDown(); | |
} | |
}, "Send UDP Block " + b); | |
udp.setDaemon(true); | |
udp.start(); | |
} | |
} | |
for (int b = 0; b < portion; b++) { | |
String prefix = "Reply[" + b + "]: "; | |
byte[] data = ("TCP Request from Sender [" + b + "]").getBytes(); | |
Thread tcp = new Thread(() -> { | |
try { | |
byte[] reply = Send.tcpblock("127.0.0.1", 8191, data); | |
System.out.println(prefix + new String(reply)); | |
} catch (IOException e) { | |
System.err.println(e); | |
} finally { | |
latch.countDown(); | |
} | |
}, "Send TCP Block " + b); | |
tcp.setDaemon(true); | |
tcp.start(); | |
} | |
latch.await(); | |
SocketUtil() { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment