在windows上从Java到C++的高效数据传输
Efficient data transfer from Java to C++ on windows
我希望将大量数据(高达~1 Gbit)从Java流式传输到C++应用程序(两者都在同一台机器上)。我目前在Linux上使用FIFO,但也需要Windows解决方案。
最跨平台的方法似乎是本地套接字,但是:a) 我不会从TCP校验和和复制到&来自内核空间,以及b) 普通用户的防火墙不会尝试检查并阻止连接吗?
似乎一个更安全的解决方案是使用JNI和命名管道API(\.\Pipe\blah),使连接的两侧都成为一个可怕的平台特定的混乱。
这真的是我的两个最佳选择吗(人们会推荐哪一个?)谢谢
您应该看看Google的Protocol Buffers,它同时支持C++和Java。
命名管道将比TCP更高效,但只使用共享内存块如何?
我不知道Java端存在哪些用于与共享内存接口的原语,但从C++端来看,访问共享内存中的数据比从套接字或命名管道中读取数据更有效。您必须实现自己的流控制和阻塞基元,但这些可能相当直接。
我会使用本地套接字,正如您所说,这是最跨平台的方法。
内核用户空间拷贝不应该是一个问题,因为除了共享内存之外,您可以选择的任何其他方法都需要这种拷贝。它在每个Unix系统上都可用,Windows也有自己的方式
要在Java中使用共享内存,唯一的方法是通过您自己的.DLL/.SO和JNI来访问它。
您最快的解决方案是内存映射共享内存段,并实现环形缓冲区或其他消息传递机制。在C++中,这是直接的,而在Java中,您有FileChannel.map方法,这使它成为可能。
下一种选择是使用这两个进程中的stdin/stdout。如果一个可以执行另一个,这可能会很快。
最后,正如您所指出的,您可以进行套接字IO。对于流式视频,这不是一个很好的选择,但如果您四处传递XML,与其他处理相比,开销将是最小的。
如果你对编写JNI很满意,可以考虑Boost.Interprocess。这将在Linux和Windows上为你提供可移植的共享内存。请记住,不存在读取/写入共享内存的内核往返。
如果它是"一个"函数调用中的一大块数据,我建议使用JNI。
看看这个:通过jni接口共享输出流
文章中的片段,它将数据从c++转移到java,相反也很容易做到:
总之,用Java共享C中的二进制数据(A/V文件、图像等)的一般策略需要字节数组。您可以在C中创建一个Java字节数组,如下所示:
const char[] rawData = {0,1,2,3,4,5,6,7,8,9}; //Or get some raw data from somewhere
int dataSize = sizeof(rawData);
printf("Building raw data array copyn");
jbyteArray rawDataCopy = env->NewByteArray(dataSize);
env->SetByteArrayRegion(rawDataCopy, 0, dataSize, rawData);
并像这样将其传递给Java:
printf("Finding callback methodn");
//Assumes obj is the Java instance that will receive the raw data via callback
jmethodID aMethodId = env->GetMethodID(env->GetObjectClass(obj),"handleData","([B)V");
if(0==aMethodId) throw MyRuntimeException("Method not found error");
printf("Invoking the callbackn");
env->CallVoidMethod(obj,aMethodId, &rawDataCopy);
你会有一个看起来像这样的Java对象:
public class MyDataHandler {
OutputStream dataStream;
public MyDataHandler(OutputStream writeTo) { dataStream = writeTo;}
public void handleData(byte[] incomingData) { dataStream.write(incomingData); }
}
该处理程序将通过本机方法传递给C,如下所示:
public class NativeIntegration {
public native void generateBinaryWithHandler(MyDataHandler handler);
//Here we assume response is something like a network stream
public void doCallNativeFunction(ResponseStream response) {
MyDataHandler handler = new MyDataHandler(response);
generateBinaryWithHandler(handler);
}
}
此外,您还可以使用其他技术:CORBA、ASN.1(ASN.1工具)、UDP或TCP
如果TCP的比特率太高,我会使用带有否定确认UDP的本地套接字(尽管我会先尝试TCP并确认它有问题)。如果您在同一台机器上进行流传输,则丢弃的数据包应该最少(如果有的话),但添加一个否定确认层可以解决这种情况。
使用System.out和System.in怎么样?
如果这不合适,那么Sockets是您的最佳选择。
如果您的C++进程启动Java进程,它可能会从继承的Channel中受益。此外,如果Java进程正在使用一个文件,我建议您探索transferTo和transferFrom方法。在进行文件到文件IO时,这些操作避免了用户和内核空间之间不必要的来回切换;如果您使用一个特殊的套接字通道,同样的优化可能会起作用。
我建议使用UDP"连接",它可以确认收到的每一个无故障的第N个数据包,并请求重新传输它将错过的几个数据包。
我建议不要使用JNI,因为它很难调试。如果C++代码Segfault或抛出一个未捕获的异常,那么JVM将崩溃,您将不知道原因。
- 如何通过ROS将realsense数据传输到其他设备
- C++中从客户端到服务器的数据传输问题
- 需要优化串行数据传输
- QTCPSOCTED数据传输在读取缓冲区已满时停止,并且在释放时不会恢复
- 分段错误:C++中的结构序列化和 MPI 数据传输
- 插座 - 数据传输后保持插座打开
- 如何避免通过TCP/IP SSH隧道在数据传输中重复读取数据
- 与GPS的串行通信-连续数据传输
- 使用 UDP 进行端口到端口数据传输
- 用于双向随机访问的 C++ 高效数据结构
- 将 cv::Mat 存储在字节数组中,以便将数据传输到服务器
- 如何使用visual studio c++与ZIGBEE进行数据传输
- 如何将数据传输到另一个线程并使helgrind知道它
- c++模块之间的数据传输
- 用于存储 3d 点的高效数据结构
- 如何修复OpenSSL不正确的数据传输
- vector 将 CSV 列数据添加到向量行中,同时将 CSV 文件的数据传输到 C++ 向量
- 使用C++测量网络上 2 个应用程序之间的数据传输速率(带宽),如何获得公正准确的结果
- 如何加快从内存到 CPU 的数据传输
- 在windows上从Java到C++的高效数据传输