使用JNA / JNI从Java线程调用C套接字函数

时间:2015-11-09 17:28:16

标签: java multithreading sockets java-native-interface jna

我必须使用具有一些套接字功能的第三方库。我无法访问源代码,但它使用了一些简单的函数:

  • OpenConn打开套接字连接
  • CloseConn以关闭连接
  • SocketRecv是一个用于接收数据的阻止函数

这些函数使用特定协议,因此我无法使用Java套接字。 编辑:我必须使用该库,因为它是一个要求。丢弃图书馆是不可能的。

这是我正在使用的代码,我将在下面介绍:

public class Test {
    private static int descriptor = -1;
    private static int numBytesRecv;
    public static byte[] buffer = new byte[255];
    public static SocketLib lib = null;

    public static void main(String[] args) throws InterruptedException{
        String server_ip = "0.0.0.0";
        lib = SocketLib.INSTANCE;
        descriptor = lib.OpenConn(server_ip);
        System.out.println("Descriptor: " + Integer.toString(descriptor));

        RecvThread t = new RecvThread();
        t.start();

        int closeResult = lib.CloseConn(descriptor);
        System.out.println("Close result: " + Integer.toString(closeResult));

        t.join();
        System.out.println("Program finish");
    }

    static class RecvThread extends Thread {
        public void run() {
            System.out.println("Starting RecvThread");
            numBytesRecv = lib.SocketRecv( descriptor, buffer, 255);
            System.out.println("Finishing RecvThread");
        }
    }

(不包括JNA定义代码)

我首先调用OpenConn在主线程中打开一个连接。 然后我用SocketRecv函数启动一个线程来等待任何数据。 然后我关闭主线程中的连接。

预期的行为是,关闭连接后,套接字关闭,接收函数被释放,程序结束。

如果我使用类似的C应用程序来测试该行为,它可以正常工作。

但是当使用JNA(如上面的代码)或JNI来调用C函数时,当我调用CloseConn函数时套接字没有关闭,因此,SocketRecv线程永远不会完成(如果没有收到数据) )。

编辑:通过调试,我确信接收线程在调用结束函数之前启动。如果在SocketRecv之前调用close函数,则SocketRecv函数不会阻塞并且其线程结束。

从Java调用CloseConn函数时,可能导致套接字未关闭的原因是什么?我已经考虑过使用单独的Java线程调用SocketRecv函数这一事实的任何问题,但我还没有发现任何类似的情况作为参考。

0 个答案:

没有答案