使用JNI/C ++代码的Java插座

 2023-01-21    234  

问题描述

我有一个Java应用程序,该应用程序可以创建一个与服务器进程交谈的套接字,例如New Java.net.socket(String Host,INT端口).该应用程序包括一堆旧的C ++代码,这些代码需要从该服务器中吸取数据并处理它.当前,通过让本机代码创建自己的套接字并连接到服务器,例如:

来实现这一点.

使用JNI/C ++代码的Java插座

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));

在Windows Vista/7机器上具有多个NIC(例如有线和WiFi或VPN连接),这两个插座最终可能会带有不同的本地地址. Java代码似乎选择一个”更好”接口(有线GB ENET =更高MTU?),本机(幼稚?)代码获取”默认”接口(粘贴在USB WiFi设备中,它将变成您的默认值 – uck) .

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

  1. 我有可能从JNI代码重新使用Java插座(Partibale?假设Sun JDK).这将完全避免问题,但是到目前为止,我看不到与Jni/本机代码中的Java.net.socket互动的任何方法.

  2. 由于第一个问题的答案可能是否定的,Java如何创建该套接字(选择接口)?代码片段受到欢迎.我已经在OpenJDK中环顾四周,但还没有找到我想要的东西.

谢谢,
克里斯

推荐答案

回答您的第一个问题:如果可以从本机代码中重复使用Java的套接字 – 是的,我不建议这样做(您会将自己与特定实现的内部联系在一起/版本);但是,如果您确实必须:使用反射来访问java.io.filedscriptor在java.net.socketimpl上,然后使用sun.misc. JavaiofiledScriptorAccess的GET方法获取本机套接字描述符. Checkout dualstackplainsocketimpl.java )

回答您的第二个问题:什么是Java的算法是什么要在windows上找到默认接口 – net_util_md.c ).

我建议您打开并使用C(JNI)代码或Java代码中的套接字,最好以后使用,因为您会发现在管理的代码中最好处理清理和错误处理插座.从C(JNI)中打开Java和通过字节缓冲区的插座的想法是完美的理智,您在合理的缓冲尺寸大小和JNI代码中的合理缓冲尺寸和适当的Deallocation上都找不到任何问题.

.

认为可以处理大量数据的Java应用程序服务器.

其他推荐答案

对于您的第一个问题,如果您在JNI代码中有java.net.Socket对象引用,则可以在其上调用方法,因此您可以通过套接字读取和写入数据.

其他推荐答案

提防在JVM实施细节中戳四周的解决方案,他们将来有可能破坏或与其他供应商VM中断.有一种方法可以使用java.nio apis进行操作.有一些方法可以与本机代码的频道通信,而无需将缓冲区复制到/java堆.

基本想法是在Java代码中创建java.nio.SocketChannel以打开连接.然后在C ++使用NewDirectByteBuffer中创建一个可以传递到频道实例的read/write方法的实例.

看 jni ni>在版本中引入的JNI增强功能1.4 java 2 sdk 和新i/o apis 有关详细信息.

以上所述是小编给大家介绍的使用JNI/C ++代码的Java插座,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/26213.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。