Created
April 25, 2016 05:14
-
-
Save EtaCassiopeia/7e4e6eebe22ccfbbfa2c5a0d6cc13711 to your computer and use it in GitHub Desktop.
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
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