`
shfzhzhr
  • 浏览: 70572 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNI实现命名管道服务器(二)——实现

    博客分类:
  • JNI
阅读更多

原理在上一篇已经说好了,在这就不再赘述了,直接上代码,代码只是实现了一个基本框架,需要完善的东西大家可以自己加:

NamedPipe.java

 

public class NamedPipe implements Pipe {
	
	static{
		System.loadLibrary("NPJNI");
	}
	
	NamedPipeInputStream is;
	NamedPipeOutputStream os;
	
	int handle = -1;
	private String name;
	
	public String getName() {
		return name;
	}



	public NamedPipe(String name){
		this.name = name;
		this.handle = this.create(name);
		if(handle == -1){
			throw new NamedPipeCreateException(name);
		}
	}
	
	
	/**
	 * 等待接受一个客户端连接(堵塞)
	 * @return
	 */
	public boolean accept(){
		return this.connect(this.handle);
	}
	
	/**
	 * 得到一个PipeInputStream以读入数据
	 */
	public PipeInputStream getInputStream() {
		if(is == null){
			is = new NamedPipeInputStream(this);
		}
		return is;
	}

	/**
	 * 得到一个PipeOutputStream以写入数据
	 */
	public PipeOutputStream getOutputStream() {
		if(os == null){
			os = new NamedPipeOutputStream(this);
		}
		return os;
	}

	/**
	 * 关闭此NamedPipe
	 */
	public void close() {
		if(this.handle != -1){
			this.close(this.handle);
		}
	}
	
	/**
	 * 断开当前的客户端连接
	 */
	public void disconnect(){
		disconnect(handle);
	}

	private native void disconnect(int handle);
	
	private native void close(int handle);
	
	private native int create(String name);
	
	private native boolean connect(int handle);
}

 

 

 

 

NamedPipeInputStream:

 

 

public class NamedPipeInputStream extends PipeInputStream {

	NamedPipe pipe;
	
	static{
		System.loadLibrary("NPJNI");
	}
	
	NamedPipeInputStream(NamedPipe pipe){
		this.pipe = pipe;
	}
	
    private native int readBytes(int handle, byte b[], int len) throws IOException;

    /**
     * 读入数据到一个beye数组(堵塞)
     * @return 实际读取的字节数
     */
    public int read(byte b[]) throws IOException {
    	return readBytes(pipe.handle, b,  b.length);
    }
    
    /**
     * 读入数据到一个beye数组(堵塞)
     * @param b
     * @return 读取信息
     */
    public ReadPipeInfo readPipe(byte b[]){
    	return this.readPipe(pipe.handle,b,b.length);
    }
	
    public native ReadPipeInfo readPipe(int handle, byte b[], int len);
}
 

 

 

NamedPipeOutputStream.java:

 

public class NamedPipeOutputStream extends PipeOutputStream {
	
	NamedPipe pipe;
	ByteArrayOutputStream buffer = new ByteArrayOutputStream();
	
	static{
		System.loadLibrary("NPJNI");
	}
	
	NamedPipeOutputStream(NamedPipe pipe){
		this.pipe = pipe;
	}
	
	/*public final NamedPipe getPipe(){
		return pipe;
	}*/
	
	private native void writeBytes(int handle, byte b[], int len)
			throws IOException;
	
	

	private native void writeBytesOff(int handle, byte b[], int offset, int len)
			throws IOException;

	/**
	 * 将一个byte数组写入管道
	 */
	public void write(byte b[]) throws IOException {
		buffer.write(b);
	}
	
	/**
	 * 将字符串s写入管道
	 * @throws IOException 
	 */
	public void write(String s) throws IOException{
		buffer.write(s.getBytes());
	}
	
	/**
	 * 将byte数组写入管道。off指定了写入的偏移值,len指定写入的长度
	 */
	@Override
	public void write(byte[] b, int off, int len) throws IOException {
		this.writeBytesOff(pipe.handle,b,off,len);
	}

	/**
	 * flush此NamedPipeOutputStream,将所有数据写入管道
	 */
	public void flush() {
		byte[] bytes = buffer.toByteArray();
		if(bytes.length > 0){
			try {
				writeBytes(pipe.handle, bytes, bytes.length);
			} catch (IOException e) {
				e.printStackTrace();
			}
			buffer = new ByteArrayOutputStream();
			flush(pipe.handle);
		}
	}
	
	private native void flush(int handle);

}
 

 

ReadPipeInfo.java:

 

public class ReadPipeInfo {

	boolean more = false;
	int count = -1;
	
	public boolean hasMoreData(){
		return this.more;
	}
	
	public int readCount(){
		return count;
	}
	
}
 

 

C++代码:

 

#define BUFSIZE 4096*500
 

JNIEXPORT jint JNICALL Java_pipe_NamedPipe_create
  (JNIEnv *env, jobject obj, jstring name)
{
	const wchar_t *str = (const wchar_t *)env->GetStringChars(name,NULL);
	if(str == NULL)
	{
		return -1;
	}
	HANDLE hPipe;
	hPipe = CreateNamedPipe( 
		str,             // pipe name 
		PIPE_ACCESS_DUPLEX,       // read/write access 
		PIPE_TYPE_MESSAGE |       // message type pipe 
		PIPE_READMODE_MESSAGE |   // message-read mode 
		PIPE_WAIT,                // blocking mode 
		PIPE_UNLIMITED_INSTANCES, // max. instances  
		BUFSIZE,                  // output buffer size 
		BUFSIZE,                  // input buffer size 
		0,                        // client time-out 
		NULL);                    // default security attribute 

	if (hPipe == INVALID_HANDLE_VALUE) 
	{
		env->ReleaseStringChars(name, (const jchar *)str);
		printf("CreatePipe failed"); 
		return -1;
	}
	env->ReleaseStringChars(name, (const jchar *)str);
	return (long)hPipe;
}


JNIEXPORT jboolean JNICALL Java_pipe_NamedPipe_connect
  (JNIEnv *env, jobject obj, jint handle)
{
	HANDLE hPipe = (void *)((int)handle);
	BOOL fConnected = ConnectNamedPipe(hPipe, NULL) ? 
         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 
	return fConnected;
}


JNIEXPORT void JNICALL Java_pipe_NamedPipe_close
  (JNIEnv *env, jobject obj, jint handle)
{
	CloseHandle((void *)((int)handle));
}


JNIEXPORT void JNICALL Java_pipe_NamedPipe_disconnect
  (JNIEnv *env, jobject obj, jint handle)
{
	HANDLE hPipe = (void *)((int)handle);
	DisconnectNamedPipe(hPipe); 
}


JNIEXPORT jint JNICALL Java_pipe_NamedPipeInputStream_readBytes
  (JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
	//jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
	char *cBuffer = new char[len+1];

	DWORD cbBytesRead;

	HANDLE hPipe = (void *)((int)handle);
	BOOL fSuccess = ReadFile( 
		hPipe,        // handle to pipe 
		cBuffer,    // buffer to receive data 
		len, // size of buffer 
		&cbBytesRead, // number of bytes read 
		NULL);        // not overlapped I/O 
	if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
	{
		delete cBuffer;
		return -1;
	}
	env->SetByteArrayRegion(buffer,0,cbBytesRead,(const jbyte *)cBuffer);
	delete cBuffer;
	return cbBytesRead;
}


JNIEXPORT jobject JNICALL Java_pipe_NamedPipeInputStream_readPipe
  (JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
	//jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
	char *cBuffer = new char[len+1];

	DWORD cbBytesRead;

	HANDLE hPipe = (void *)((int)handle);
	BOOL fSuccess = ReadFile( 
		hPipe,        // handle to pipe 
		cBuffer,    // buffer to receive data 
		len, // size of buffer 
		&cbBytesRead, // number of bytes read 
		NULL);        // not overlapped I/O 

	DWORD le = GetLastError();

	if (! fSuccess && le != ERROR_MORE_DATA)
	{
		jclass jclass = env->FindClass("pipe/ReadPipeInfo");   
		jfieldID moreData = env->GetFieldID(jclass,"more","Z");   
		jfieldID count = env->GetFieldID(jclass,"count","I");  

		jmethodID mID = env->GetMethodID(jclass, "<init>", "()V");
		jobject info = env->NewObject(jclass,mID); 
		delete cBuffer;
		env->SetBooleanField(info,moreData,false);
		env->SetIntField(info,count,-1);
		env->DeleteLocalRef(jclass);
		return info;
	}

	jclass jclass = env->FindClass("pipe/ReadPipeInfo");   
    jfieldID moreData = env->GetFieldID(jclass,"more","Z");   
    jfieldID count = env->GetFieldID(jclass,"count","I");  
  
	jmethodID mID = env->GetMethodID(jclass, "<init>", "()V");
	jobject info = env->NewObject(jclass,mID); 

	
	env->SetByteArrayRegion(buffer,0,cbBytesRead,(const jbyte *)cBuffer);
	delete cBuffer;
	    
	if(le == ERROR_MORE_DATA){
		env->SetBooleanField(info,moreData,true);
	}else{
		env->SetBooleanField(info,moreData,false);
	}
	
	env->SetIntField(info,count,cbBytesRead);
    //env->SetShortField(info,count,10);  
	env->DeleteLocalRef(jclass);
      
    return info;   
}


JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_writeBytes
  (JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint len)
{
	jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
	
	DWORD cbWritten;
	HANDLE hPipe = (void *)((int)handle);
	// Write to the pipe. 
	BOOL fSuccess = WriteFile( 
		hPipe,        // handle to pipe 
		jBuffer,      // buffer to write from 
		len, // number of bytes to write 
		&cbWritten,   // number of bytes written 
		NULL);        // not overlapped I/O
}


JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_writeBytesOff
  (JNIEnv *env, jobject obj, jint handle, jbyteArray buffer, jint off, jint len)
{
	jbyte *jBuffer = env->GetByteArrayElements(buffer,NULL);
	
	DWORD cbWritten;
	HANDLE hPipe = (void *)((int)handle);
	// Write to the pipe. 
	BOOL fSuccess = WriteFile( 
		hPipe,        // handle to pipe 
		jBuffer+off,      // buffer to write from 
		len, // number of bytes to write 
		&cbWritten,   // number of bytes written 
		NULL);        // not overlapped I/O
}


JNIEXPORT void JNICALL Java_pipe_NamedPipeOutputStream_flush
  (JNIEnv *env, jobject obj, jint handle)
{
	HANDLE hPipe = (void *)((int)handle);
	BOOL flag = FlushFileBuffers(hPipe);
}
 

 

 

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    Java中JNI的使用(一)——native

    这篇博客文章“Java中JNI的使用(一)——native”很可能是对Java程序员如何首次接触和使用JNI的一个入门教程。 首先,我们来理解“native”关键字。在Java中,`native`是用来标记一个方法的,表示这个方法的实现是在...

    Java中JNI的使用(二)——参数传递

    NULL 博文链接:https://zhoucl.iteye.com/blog/1101661

    JNI编程(二) —— 让C++和Java相互调用(2)

    这篇博客“JNI编程(二) —— 让C++和Java相互调用(2)”显然深入探讨了如何利用JNI实现Java与C++之间的互调用。在Java应用程序中,有时为了性能优化或者利用已有的C/C++库,我们需要借助JNI来实现这种跨语言的通信。 ...

    Java(JNI) 连接OPC服务器 读写数据 完整源代码

    在本案例中,JNI被用来连接OPC(OLE for Process Control)服务器,这是一种工业自动化领域的标准接口,用于不同设备和系统之间的数据交换。 OPC服务器是一个中间件,它提供了与工业控制系统设备通信的标准接口。...

    Android中JNI实现AES加密源代码

    综上所述,"Android中JNI实现AES加密源代码"涉及的知识点包括Android JNI的使用、AES加密算法的实现、NDK开发环境的配置、C/C++与Java的交互,以及数据安全和性能优化。通过这样的实现,开发者可以在Android应用中...

    JNI实现原理权威指南

    JNI(Java Native Interface)是Java语言的一个重要特性,它允许Java代码和其他语言编写的本地代码进行交互,这在Java应用中实现与底层系统特定功能的访问时尤其有用。要深入理解JNI的实现原理,本书《JNI实现原理...

    Android下AES加密算法的JNI实现(包含SO文件)

    在Android开发中,有时为了提高性能或利用C/C++库的优势,我们会选择使用JNI(Java Native Interface)来实现部分功能。本资源提供了一个具体的实例,即在Android环境下使用JNI实现AES(Advanced Encryption ...

    androidjni实现本地加解密数据,使用C++语言编写,基于openssl实现 集成RSAAES3DESBASE64MD5

    本项目主要探讨了如何使用C++语言通过JNI(Java Native Interface)与Android应用交互,实现基于OpenSSL库的加解密算法,包括RSA、AES、3DES、BASE64和MD5。以下是关于这些技术的详细解释: 1. **JNI(Java Native ...

    安卓手机音频调用JNI实现

    "安卓手机音频调用JNI实现"的项目就是利用JNI来优化音频处理的效率,减少时间延迟,提升用户体验。 JNI在Android中的应用主要涉及以下几个方面: 1. **性能优化**:Java虚拟机(JVM)对于一些底层操作,如硬件直接...

    java通过jni实现口令屏蔽

    Java 通过JNI(Java Native Interface)实现口令屏蔽是一种在Java应用程序中安全处理敏感数据,如密码或密钥,的方法。JNI是Java平台提供的一种机制,允许Java代码和其他语言写的代码进行交互。在这个场景中,C++代码...

    JNI实现示例DEMO

    熟练掌握JNI能够帮助你充分利用Java的跨平台特性,同时结合本地代码的优势,提升应用性能或者实现特定功能。在进行JNI编程时,确保理解并正确处理内存管理、线程安全以及错误处理是非常重要的。

    jni例子——使用int数组

    在这个“jni例子——使用int数组”的示例中,我们将深入探讨如何在Java和C/C++之间传递和操作int数组。 1. **JNI基础知识**: - JNI接口提供了Java与本地代码(如C/C++)通信的桥梁,使得开发者可以在Java应用中...

    JNI实现回调及JNI开启线程

    本示例中,我们将深入探讨如何使用JNI实现回调机制以及在JNI中开启线程。 1. **JNI回调JAVA的函数**: 在Java中,我们通常通过定义`native`关键字声明本地方法,这些方法将在JNI层实现。为了在JNI中调用Java的方法...

    yuv420p转yuv420sp jni实现

    yuv420p转yuv420sp的jni实现 修改下全类名就可以使用

    使用jni和DES实现两次加密

    标题中的“使用JNI和DES实现两次加密”是指在Java编程中结合使用JNI(Java Native Interface)和DES(Data Encryption Standard)加密算法来实现双重安全保护的一种技术。这种技术通常用于提高程序的安全性,防止数据在...

    springboot 集成seetaface6JNI实现人脸检测识别

    在本文中,我们将深入探讨如何将SeetaFace6JNI集成到SpringBoot应用中,实现高效的人脸检测和识别功能。SeetaFace6JNI是SeetaFace6库的一个Java封装,它提供了一种与Java应用程序交互的方式,使得在Java环境中也能...

    JNI实现高斯模糊图片

    本主题探讨的是如何利用JNI来实现高斯模糊图片的功能。高斯模糊是一种图像处理技术,通过模拟人类视觉系统对图像进行平滑处理,减少图像的噪声和细节,使图像呈现出柔和的效果。 首先,我们要理解高斯模糊的基本...

    通过JNI实现C++与JAVA相互调用之TCP编程

    在这个"通过JNI实现C++与JAVA相互调用之TCP编程"的示例中,我们探讨的是如何使用JNI来实现TCP通信,其中C++作为底层通信引擎,而Java则负责上层应用逻辑。 首先,TCP(Transmission Control Protocol)是一种面向...

Global site tag (gtag.js) - Google Analytics