Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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/2/ssis/2.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
Java 使用JNI/C++;代码_Java_C++_Sockets_Java Native Interface - Fatal编程技术网

Java 使用JNI/C++;代码

Java 使用JNI/C++;代码,java,c++,sockets,java-native-interface,Java,C++,Sockets,Java Native Interface,我有一个java应用程序,它创建了一个与服务器进程对话的套接字,例如新的java.net.socket(stringhost,int-port)。这个应用程序包括一组遗留的C++代码,需要从服务器中抽取大量数据并处理它。目前,这是通过让本机代码创建自己的套接字并连接到服务器来实现的,例如: sock = socket(AF_INET, SOCK_STREAM, 0); struct hostent* hp = gethostbyname(host); if (!hp) { unsigned

我有一个java应用程序,它创建了一个与服务器进程对话的套接字,例如新的java.net.socket(stringhost,int-port)。这个应用程序包括一组遗留的C++代码,需要从服务器中抽取大量数据并处理它。目前,这是通过让本机代码创建自己的套接字并连接到服务器来实现的,例如:

sock = socket(AF_INET, SOCK_STREAM, 0);
struct hostent* hp = gethostbyname(host);
if (!hp)
{
  unsigned long addr = inet_addr(host);
  hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
}

struct sockaddr_in name;
name.sin_family = AF_INET;
memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
name.sin_port = htons(port);

connect(sock, (sockaddr*)&name, sizeof(name));
在具有多个NIC(如有线和wifi或vpn连接)的Windows vista/7计算机上,这两个套接字最终可能具有不同的本地地址。java代码似乎选择了一个“更好”的接口(有线Gb enet=更高的MTU?),而本地(naive?)代码则选择了“默认”接口(插入usb wifi设备,它会成为您的默认接口-真恶心)

这给我带来了一些问题,我不认为细节是相关的。两个问题:

  • 我是否可以从JNI代码中重用java套接字(可移植?假设是Sun JDK)。这将完全避免这个问题,但到目前为止,我还没有看到任何与JNI/本机代码中的java.net.Socket内容交互的方法

  • 因为第一个问题的答案可能是否定的,所以java是如何创建套接字的(选择接口)?欢迎使用代码片段。我在openjdk的资料中四处寻找,但没有找到我要找的东西

  • 谢谢,
    Chris

    对于第一个问题,如果您的JNI代码中有一个
    java.net.Socket
    对象引用,您可以调用它上的方法,这样您就可以通过Socket读写数据了。

    您的第二个问题-

    您可以始终“绑定”到所需的本地接口(只需要它的Ip地址)

    公共无效绑定(SocketAddress addr)
    抛出SocketException将此DatagramSocket绑定到特定的地址和端口以回答您的第一个问题:如果可以从本机代码中重用Java的socket——是的,这是可能的,但我不建议这样做(您将自己绑定到特定实现/版本的内部);但如果您确实必须:使用反射来访问java.net.SocketImpl上的java.io.FileDescriptor,然后使用sun.misc。JavaIOFileDescriptorAccess的get方法来获取本机套接字描述符。结帐)

    回答您的第二个问题:在windows上查找默认接口的Java算法是什么——签出getDefaultIPv6Interface方法(不要让v6愚弄您——我相信它也用于v4)

    我建议您从C(JNI)代码或Java代码(最好是后者)打开并使用套接字,因为您会发现清理和错误处理最好在管理套接字的代码中处理。在Java中打开套接字并从C(JNI)传递字节缓冲区的想法是完全正确的,并且在JNI代码中合理的缓冲区大小和适当的释放上,您不应该发现堆有任何问题


    试想一下处理大量数据的Java应用程序服务器。

    小心那些涉及JVM实现细节的解决方案,它们很可能在将来或使用其他供应商的虚拟机时崩溃。有一种方法可以通过使用
    java.nio
    API进行移植。有一些方法可以从本机代码与通道通信,而无需将缓冲区复制到java堆或从java堆复制缓冲区

    基本思想是在java代码中创建
    java.nio.SocketChannel
    ,以打开连接。然后在C++使用<代码> NewDirectByteBuffer < /C>中创建一个<代码> java .Nio。ByteBuffer < /C>实例,该实例可以传递到<实例> > <代码> > />代码>编写< /COD>通道实例的方法。
    查看和了解详细信息。

    我想不出为什么Java会选择比启用代码“更好”的本地接口。它所做的只是调用本机代码,与您自己的代码非常相似。您可能会看到一些依赖顺序而不是依赖Java的内容。

    您可以提供一个SocketImpl子类,该子类具有自己的基于JNI函数的FileDescriptor,该函数公开了本机套接字。正如你在JNI中一样,你必须考虑平台(抽象),但是你独立于java实现,根据所接受的答案是主要风险。
    SocketImpl类是由Socket.setSocketImplFactory()和合适的工厂部署的。

    在Java中调用bind听起来并没有什么帮助——它已经选择了最好的接口。但是获取Java套接字的本地地址,然后在本机端调用bind以使用相同的接口听起来是一种合理的方法。Ben,这实际上就是我所做的,但是我有一个报告说本机套接字无法连接到服务器(在将其绑定到与Java套接字相同的本地地址之后)。我还没有弄清楚它失败的原因,这就是我想看看java实现的原因。谢谢Zoran,我会看一看。-1建议在私有JVM实现细节中捣乱。你有没有读过这个问题,以及我对这个问题的回答?也许您希望提供一个不访问私有JVM实现细节的解决方案?不再提供“net_util_md.c”存储库。我可以想到几个原因,但我无法说出实际的原始原因。然而,正如佐兰所指出的,这种行为是不同的。java代码使用SIO_ROUTING_INTERFACE_查询调用WSAIoctl以获取接口。在这一点上,我倾向于完全摆脱本机套接字代码。