Skip to content

Instantly share code, notes, and snippets.

@EtaCassiopeia
Created April 25, 2016 05:14
Show Gist options
  • Save EtaCassiopeia/7e4e6eebe22ccfbbfa2c5a0d6cc13711 to your computer and use it in GitHub Desktop.
Save EtaCassiopeia/7e4e6eebe22ccfbbfa2c5a0d6cc13711 to your computer and use it in GitHub Desktop.
package com.github.etacassiopeia.jna;
import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import sun.nio.ch.DatagramSocketAdaptor;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.DatagramSocket;
import java.nio.channels.DatagramChannel;
/**
* <h1>SocketHelper</h1>
*
* @author Mohsen Zainalpour
* @version 1.0
* @since 24/04/16
*/
/**
* sample usage :
*
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
socket.setReuseAddress(true);
SocketHelper.setSockOpt(socket, SocketHelper.SOL_SOCKET, SocketHelper.SO_REUSEPORT, 1);
channel.socket().bind(new InetSocketAddress(5146));
*/
public class SocketHelper {
public static int SO_REUSEPORT = 15;
public static int SOL_SOCKET = 1;
static {
Native.register("c");
}
private SocketHelper() {
}
private static native int setsockopt(int fd, int level, int option_name, Pointer option_value, int option_len) throws LastErrorException;
public static void setSockOpt(DatagramSocket socket, int level, int option, int option_value) throws IOException {
if (socket instanceof DatagramSocketAdaptor) {
DatagramSocketAdaptor datagramSocketAdaptor = (DatagramSocketAdaptor) socket;
try {
Method getChannelMethod = DatagramSocketAdaptor.class.getDeclaredMethod("getChannel");
getChannelMethod.setAccessible(true);
DatagramChannel datagramChannelImplInstance = (DatagramChannel) getChannelMethod.invoke(datagramSocketAdaptor);
Field fileDescriptorField = datagramChannelImplInstance.getClass().getDeclaredField("fd");
fileDescriptorField.setAccessible(true);
FileDescriptor fileDescriptorInstance = (FileDescriptor) fileDescriptorField.get(datagramChannelImplInstance);
Field numericFdValue = FileDescriptor.class.getDeclaredField("fd");
numericFdValue.setAccessible(true);
int fd = (int) numericFdValue.get(fileDescriptorInstance);
IntByReference val = new IntByReference(option_value);
setsockopt(fd, level, option, val.getPointer(), 4);
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment