先贴代码吧生成到H头文件/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Serial */#ifndef _Included_Serial
#define _Included_Serial
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Serial
 * Method:    OpenDev
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_Serial_OpenDev
  (JNIEnv *, jobject, jstring);/*
 * Class:     Serial
 * Method:    set_speed
 * Signature: (II)V
 */
JNIEXPORT void JNICALL Java_Serial_set_1speed
  (JNIEnv *, jobject, jint, jint);/*
 * Class:     Serial
 * Method:    set_Parity
 * Signature: (IIII)I
 */
JNIEXPORT jint JNICALL Java_Serial_set_1Parity
  (JNIEnv *, jobject, jint, jint, jint, jint);#ifdef __cplusplus
}
#endif
#endif
C代码#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <jni.h>
#include "Serial.h"int speed_arr[]={B38400, B19200, B9600, B4800, B2400, B1200, B300,
    B38400, B19200, B9600, B4800, B2400, B1200, B300,};
int name_arr[]={38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
    19200, 9600, 4800, 2400, 1200, 300,};JNIEXPORT jint JNICALL Java_Serial_OpenDev
  (JNIEnv *env, jobject obj, jstring Dev)
{
    const char *Dev_utf = (*env)->GetStringUTFChars(env, Dev, JNI_FALSE);
    int fd = open(Dev_utf, O_RDWR|O_NOCTTY);
    (*env)->ReleaseStringUTFChars(env, Dev, Dev_utf);
    if(-1 == fd)
    {
        perror("Can't Open Serial Port\n");
        return -1;
    }
    else
    {
        printf("Serial Open\n");
        return fd;
    }
}JNIEXPORT void JNICALL Java_Serial_set_1speed
  (JNIEnv *env, jobject obj, jint fd, jint speed)
{
    int i;
    int status;
    struct termios Opt;
    tcgetattr(fd, &Opt);
    for(i=0; i<sizeof(speed_arr)/sizeof(int); i++)
    {
        if(speed == name_arr[i])
        {
            tcflush(fd, TCIOFLUSH);
            cfsetispeed(&Opt, speed_arr[i]);
            cfsetospeed(&Opt, speed_arr[i]);
            status = tcsetattr(fd, TCSANOW, &Opt);
            if(status != 0)
                perror("tcsetattr fd1");
            return ;
        }
        tcflush(fd, TCIOFLUSH);
    }
}JNIEXPORT jint JNICALL Java_Serial_set_1Parity
  (JNIEnv *env, jobject obj, jint fd, jint databits, jint stopbits, jint parity)
{
    struct termios opt;
    if(tcgetattr(fd, &opt) != 0)
    {
        perror("SetupSerial 1");
        return -1;
    }
    opt.c_cflag &= ~CSIZE;
    opt.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
    opt.c_oflag &= ~OPOST;    switch(databits)
    {
        case 7: opt.c_cflag |= CS7; break;
        case 8: opt.c_cflag |= CS8; break;
        default: fprintf(stderr, "Unsupported data size\n"); 
             return -1;
    }
    switch(parity)
    {
        case 'n': 
        case 'N': opt.c_cflag &= ~PARENB;
              opt.c_iflag &= ~INPCK;
              break;
        case 'o':
        case 'O': opt.c_cflag |= (PARODD|PARENB);
              opt.c_iflag |= INPCK;
              break;
        case 'e':
        case 'E': opt.c_cflag |= PARENB;
              opt.c_cflag &= ~PARODD;
              opt.c_iflag |= INPCK;
              break;
        case 's':
        case 'S': opt.c_cflag &= ~PARENB;
              opt.c_cflag &= ~CSTOPB;
              break;
        default: fprintf(stderr, "Unsupported parity\n");
             return -1;
              
    }
    switch(stopbits)
    {
        case 1: opt.c_cflag &= ~CSTOPB; 
                           break; 
        case 2: opt.c_cflag |= CSTOPB;            
            break;
        default: fprintf(stderr,"Unsupported stop bits\n"); 
             return -1; 
    }    if (parity != 'n')  opt.c_iflag |= INPCK;
//    tcflush(fd,TCIFLUSH);
    opt.c_cc[VTIME] = 150; /* 设置超时 15 seconds*/  
    opt.c_cc[VMIN] = 0; 
    tcflush(fd, TCIFLUSH);
    if (tcsetattr(fd,TCSANOW,&opt) != 0)  
    {
        perror("SetupSerial 3");  
        return -1; 
    }
     return 0; 
}
JAVA文件
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;public class Serial {    public native int OpenDev(String Dev);
    public native void set_speed(int fd, int speed);
    public native int set_Parity(int fd, int databits, int stopbits, int parity);
    
    static{
        System.loadLibrary("Serial");
    }    public static void main(String[] args) {
        int fd;
        Serial serialPort = new Serial();
        fd = serialPort.OpenDev("/dev/ttyUSB0"); 
}
C语言部分在linux下面已经通了,可以正常读写串口。
上述代码可以正常打开串口(我这里用到是USB转串口)并且显示Serial Open,但是接下来要如何进行数据到输入和输出呢?网上看到有人说要用java到I/O留进行操作,但是在读写串口到时候如何制定串口设备呢?比如用FileInputStream和FileOutputStream那他们到型参怎么指定呢?这里打开串口后返回到是int型到fd,应该不能像在linux下那样直接read和write吧,困扰我好几天了,希望高手能帮我看看。

解决方案 »

  1.   

    串口的读写操作应该还是用C来实现
    仿照你的set_speed或set_Parity方法用JNI的方式实现串口的读写
      

  2.   

    这个我也想过  但是网上说进行JNI调用很花费时间,大概几百毫秒,在串口数据量比较大时候频繁调用JNI进行读写可能会有很严重的丢包吧?
      

  3.   

    本地文件方式比较笨,时效性差,可以给你简单说一下,就是java把数据文件存在本地磁盘,然后c去监听这个目录,发现有新文件,加把文件内容读近来处理!应该会有更好的解决办法,只是我没接触过这方面,所以不能给你太多建议.
      

  4.   

    谢谢你的建议,我现在是按照qybao的方法,读写也用JNI,但是在读取字段到末尾总会有多读或者错读,正在想办法改进
      

  5.   

    应该是buffer的问题,例如你的byte定义长度为100,可是数据只有60,后面的40就是脏数据.不知道你遇到的是不是这个问题.如果是通常传输的时候可以携带数据长度,或者定义结束符来解决.
      

  6.   


    已经解决了,read是这么写的JNIEXPORT jstring JNICALL Java_Serial_read
      (JNIEnv *env, jobject obj, jint fd, jint len)
    {
        int nread=0;
        char tempBuff[len];
        jstring jstr;
        bzero(tempBuff, sizeof(tempBuff));
        while((nread = read(fd, tempBuff, len))>0)
        {    
            tempBuff[nread+1] = '\0';
            jstr = (*env)->NewStringUTF(env, tempBuff);
            return jstr;
        }
    }在主函数里我把每次读回来到数据用concat()函数拼接在一起就可以了,谢谢各位了,结贴