Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JNA/JNI从Java线程调用C套接字函数_Java_Multithreading_Sockets_Java Native Interface_Jna - Fatal编程技术网

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

使用JNA/JNI从Java线程调用C套接字函数,java,multithreading,sockets,java-native-interface,jna,Java,Multithreading,Sockets,Java Native Interface,Jna,我必须使用具有一些套接字函数的第三方库。我无法访问源代码,但它使用了一些简单的函数: OpenConn以打开套接字连接 CloseConn关闭连接 SocketRecv是一个用于接收数据的阻塞函数 这些函数使用特定的协议,因此我不能使用Java套接字。 编辑:我必须使用库,因为这是一项要求。无法丢弃该库 这是我正在使用的代码,我将在下面描述: public class Test { private static int descriptor = -1; private sta

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

  • 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函数的问题,但我没有发现类似的情况作为参考。

“这些函数使用特定的协议,因此我不能使用Java套接字”是一个非序列。我建议最好用Java重新实现协议,而不是将JNI/JNA引入您的系统。当然,最好只使用Java代码(或C代码,因为它可以像我写的那样工作)。我可能没有在那里使用正确的词语。我想指出的是,这里需要使用C库,它们的函数不能用Java或其他语言重新实现,只能使用Propitary库(即使我可以使用反向工程来解码协议)。编辑:它必须集成到Java应用程序中。不能保证在关闭套接字时接收线程已经开始运行。什么代码负责设置侦听套接字?如果是
SocketRecv
,那么您可能应该启动该线程并等待信号,然后再尝试连接。根据创建的套接字类型,不一定会向侦听器发送任何“关闭”指示(例如,UDP套接字是无连接的)。@technomage库使用TCP套接字。我希望代码示例保持简单,但我确信SocketRecv线程是在结束部分运行之前运行的。有一个外部服务器套接字正在侦听,OpenConn作为客户端连接。SocketRecv等待来自服务器的消息,当收到任何消息或使用CloseConn关闭连接时,它应该结束。这里的问题是,当使用Java和JNA/JNI来运行库时,库不能像预期的那样工作,但是如果我从C应用程序运行它,它工作得很好。Enrique,您如何知道接收线程代码在连接关闭之前运行?你这么说,但你怎么知道?您是否尝试过在调用lib.SocketRecv之前关闭连接会发生什么情况?我认为technomage在这方面可能是正确的。在C或Java中运行相同代码的唯一区别是线程。