我必须使用具有一些套接字功能的第三方库。我无法访问源代码,但它使用了一些简单的函数:
这些函数使用特定协议,因此我无法使用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函数这一事实的任何问题,但我还没有发现任何类似的情况作为参考。