如题,本人在写一个CAN总线的JNI库供上层的Java应用层序调用。由于can的kernel底层驱动是适用的socketcan架构,所以JNI库里面是适用linux socket编程来调用驱动.我发现 在JNI库里面调用socket(AF_INET, SOCK_DGRAM, 0)失败,返回值是0xffffffff。请问大侠们有没有遇到类似的问题?给些建议吗?android jni socket 

解决方案 »

  1.   

    这个根socket没有关系吧,估计sokcet接收命令后处理返回的结果不对
      

  2.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?
      

  3.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?这样,首先你先确保socket整个调用流程是否正确
    然后你看看socket接收命令后处理那块是否正确.
      

  4.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?这样,首先你先确保socket整个调用流程是否正确
    然后你看看socket接收命令后处理那块是否正确.我是上层JNI代码,socket是linux标准API,我没有必要去管理socket里面的实现吧?无论如何,我运行一下“socket(AF_INET, SOCK_DGRAM, 0)”应该不会失败吧?
      

  5.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?这样,首先你先确保socket整个调用流程是否正确
    然后你看看socket接收命令后处理那块是否正确.我是上层JNI代码,socket是linux标准API,我没有必要去管理socket里面的实现吧?无论如何,我运行一下“socket(AF_INET, SOCK_DGRAM, 0)”应该不会失败吧?嗯,应该不会失败.我在想adb shell和jni里面调很大的区别就是adb shell里面有root权限...其它我不知道你的代码,所以不是很清楚.
      

  6.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?这样,首先你先确保socket整个调用流程是否正确
    然后你看看socket接收命令后处理那块是否正确.我是上层JNI代码,socket是linux标准API,我没有必要去管理socket里面的实现吧?无论如何,我运行一下“socket(AF_INET, SOCK_DGRAM, 0)”应该不会失败吧?嗯,应该不会失败.我在想adb shell和jni里面调很大的区别就是adb shell里面有root权限...其它我不知道你的代码,所以不是很清楚.也不对,想了半天,没你的代码,不知道问题在哪
      

  7.   


    那为什么 “sokcet接收命令后处理返回的结果不对” ?这样,首先你先确保socket整个调用流程是否正确
    然后你看看socket接收命令后处理那块是否正确.我是上层JNI代码,socket是linux标准API,我没有必要去管理socket里面的实现吧?无论如何,我运行一下“socket(AF_INET, SOCK_DGRAM, 0)”应该不会失败吧?嗯,应该不会失败.我在想adb shell和jni里面调很大的区别就是adb shell里面有root权限...其它我不知道你的代码,所以不是很清楚.也不对,想了半天,没你的代码,不知道问题在哪怎么把代码传给你看看?你有邮箱吗?
      

  8.   


    unsigned int if_nametoindex(const char *ifname)
    {
        int index;
        int ctl_sock;
        struct ifreq ifr;    memset(&ifr, 0, sizeof(struct ifreq));
        strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;    index = 0;
        if ((ctl_sock = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
            if (ioctl(ctl_sock, SIOCGIFINDEX, &ifr) >= 0) {
                index = ifr.ifr_ifindex;
            }
            close(ctl_sock);
        }
        return index;
    }
    static int do_set_nl_link(int fd, __u8 if_state, const char *name,
      struct req_info *req_info)
    {
    struct set_req req; const char *type = "can"; memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
    req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
    req.n.nlmsg_type = RTM_NEWLINK;
    req.i.ifi_family = 0;  fprintf(stdout, "1if_nametoindex %s \n", name);
    req.i.ifi_index = if_nametoindex(name);
    // req.i.ifi_index = devicesindex;
      fprintf(stdout, "22245if_nametoindex %s %d\n", name, req.i.ifi_index);
    if (req.i.ifi_index == 0) {
    fprintf(stderr, "Cannot find device \"%s\"\n", name);
    return -1;
    } if (if_state) {
    switch (if_state) {
    case IF_DOWN:
    req.i.ifi_change |= IFF_UP;
    req.i.ifi_flags &= ~IFF_UP;
    break;
    case IF_UP:
    req.i.ifi_change |= IFF_UP;
    req.i.ifi_flags |= IFF_UP;
    break;
    default:
    fprintf(stderr, "unknown state\n");
    return -1;
    }
    } if (req_info != NULL) {
    /* setup linkinfo section */
    struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
    addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
    addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type,
      strlen(type));
    /* setup data section */
    struct rtattr *data = NLMSG_TAIL(&req.n);
    addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); if (req_info->restart_ms > 0 || req_info->disable_autorestart)
    addattr32(&req.n, 1024, IFLA_CAN_RESTART_MS,
      req_info->restart_ms); if (req_info->restart)
    addattr32(&req.n, 1024, IFLA_CAN_RESTART, 1); if (req_info->bittiming != NULL) {
    addattr_l(&req.n, 1024, IFLA_CAN_BITTIMING,
      req_info->bittiming,
      sizeof(struct can_bittiming));
    } if (req_info->ctrlmode != NULL) {
    addattr_l(&req.n, 1024, IFLA_CAN_CTRLMODE,
      req_info->ctrlmode,
      sizeof(struct can_ctrlmode));
    } /*  end of data section */
    data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; /*  end of link info section */
    linkinfo->rta_len =
        (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
    } return send_mod_request(fd, &req.n);
    }
      

  9.   


    你在adb shell里面run的是一个bin文件吧,你现在把这个bin改造成jni调用就不成功了.你有系统源码的吧.
    我在想你不用改造,将bin文件做成init.rc里面的服务,在jni里通过ctrl.start这个方式启这个服务,跟你在adb shell里面是一样的效果.
      

  10.   


    你在adb shell里面run的是一个bin文件吧,你现在把这个bin改造成jni调用就不成功了.你有系统源码的吧.
    我在想你不用改造,将bin文件做成init.rc里面的服务,在jni里通过ctrl.start这个方式启这个服务,跟你在adb shell里面是一样的效果.您分析的很对。我的bin文件运行正常。
    谢谢您的建议。但是我要自己做JAVA UI的。我的java应用程序需要发送的数据以及从CAN总线接收的数据如何传给JAVA代码?
      

  11.   

    我知道了问题的答案,是权限问题。当我在调用JNI库的java程序里面添加, <uses-permission android:name="android.permission.INTERNET" /> ,socket(AF_INET, SOCK_DGRAM, 0)运行成功了AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.samkoon.can"
        android:versionCode="1"
        android:versionName="1.0"
        android:sharedUserId="android.uid.system">    <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
        
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="16" />    <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
      

  12.   

    楼主,追问你一个问题
    rc = ioctl(sockfd, SIOCSARP, &req);
    我试图设置android的arp绑定功能,发现上面这个函数总是执行不成功,楼主能帮忙分析下吗?