您的位置:首页 > 移动开发 > Android开发

在Android上使用LocalSocket实现上层Java和底层C++的通信

2013-01-15 11:24 701 查看
  
在看Android代码的时候发现有使用LocalSocket,比java本身的socket效率要高,好像没有经过协议栈,是android自己实现的类似共享内存一样的东东,在传输大量数据的时候就需要用到,比如视频数据,在RIL电话那部分也用到。刚好项目用到视频传输,我试用了一把,果然不错!

public static final String SOCKET_ADDRESS = "socket_cmmb_sim_command";//这个名字要记好,在接受端要用到,可以理解为共享内存的设备文件名。

.....

            try {

                LocalServerSocket server = new LocalServerSocket(SOCKET_ADDRESS);

                while (true) {

                    //Log.i(TAG, "begin accept");

                    LocalSocket receiver = server.accept();

                    if (receiver != null) {

                        InputStream input = receiver.getInputStream();

                        byte[] bytes = new byte[4];

                        int size = input.read(bytes, 0, 4);

                        if(size!=4) Log.i(TAG, "received command len:" + String.valueOf(size));

                        int cmd_len = ((bytes[0] & 0xFF) << 24)|((bytes[1] & 0xFF) << 16)

                                |((bytes[2] & 0xFF) << 8)|(bytes[3] & 0xFF);

                        Log.i(TAG, "received cmd_len:"+String.valueOf(cmd_len));

                        if(cmd_len>0){

                            byte[] ArrayOfByte = new byte[cmd_len];

                            size = input.read(ArrayOfByte, 0, cmd_len);

                            Log.i(TAG, "received data len:" + String.valueOf(size));

                            Parcel parcel = Parcel.obtain();

                            parcel.unmarshall(ArrayOfByte, 0, ArrayOfByte.length);

                            parcel.setDataPosition(0);

                            processRequest(receiver,parcel);

                        }

                    }

                }

            } catch (IOException e) {

                Log.e(getClass().getName(), e.getMessage());

            }

        private void sendResult(LocalSocket paramLocalSocket, Parcel paramParcel) throws IOException{

            byte[] arrayOfByte1 = new byte[4];

            byte[] arrayOfByte2 = paramParcel.marshall();

            Log.i(TAG, "enter sendResult!");

            arrayOfByte1[0] = 0;

            arrayOfByte1[1] = 0;

            arrayOfByte1[2] = (byte)(arrayOfByte2.length >> 8 & 0xFF);

            arrayOfByte1[3] = (byte)(arrayOfByte2.length & 0xFF);

            paramLocalSocket.getOutputStream().write(arrayOfByte1);

            paramLocalSocket.getOutputStream().write(arrayOfByte2);

        }

private void processRequest(LocalSocket paramLocalSocket, Parcel paramParcel)

{

          int cmd = paramParcel.readInt();

          //Log.i(TAG,"parcel:"+String.valueOf(cmd));

          if(cmd>0&&cmd<CMMB_REQUEST_CMD_MAX){

          //String info = "unknown";

          Parcel parcel_info = Parcel.obtain();

          TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

          switch (cmd)

          {

          case CMMB_REQUEST_GET_IMSI:{

              Log.i(TAG, "received CMMB_REQUEST_GET_IMSI command!");

              /*

               * 唯一的用户ID:

               * 例如:IMSI(国际移动用户识别码) for a GSM phone.

               * 需要权限:READ_PHONE_STATE

               */

              String info = tm.getSubscriberId();//String

              if(info!=null) Log.i(TAG, info);

              parcel_info.writeInt(CMMB_REQUEST_GET_IMSI);

              parcel_info.writeString(info);

            }

            break;

....

          try {

             sendResult(paramLocalSocket, parcel_info);

          } catch (IOException e) {

            // TODO Auto-generated catch block

            Log.e(getClass().getName(), e.getMessage());

            e.printStackTrace();

          }

}

以上是服务器端,下面是客户端

#define  SOCKET_NAME_CMMB_SIM_COMMAND   "socket_cmmb_sim_command"

...

    fd = socket_local_client(

                            SOCKET_NAME_CMMB_SIM_COMMAND,

                            ANDROID_SOCKET_NAMESPACE_ABSTRACT,

                            SOCK_STREAM );

    //check open failed

    if (fd < 0)

    {

           LOGE("Failed to open socket: %s\n\r'", SOCKET_NAME_CMMB_SIM_COMMAND);

        goto error;

        }

    //get command data

    p_request.writeInt32 (CMMB_REQUEST_GET_IMSI);

    data = (char *)p_request.data();

    datasize = (int)p_request.dataSize();

    //get command length

    dataLength[0] = dataLength[1] = 0;

    dataLength[2] = (char)((datasize >> 8) & 0xff);

    dataLength[3] = (char)(datasize & 0xff);

    //write command getimsi length

    if(SmsMbbmsSimSocketWrite(fd, dataLength, sizeof(dataLength)) != sizeof(dataLength))

    {

        LOGE("Failed to write cmmand %d 's length to socket: %s!!!!!\n'", CMMB_REQUEST_GET_IMSI, SOCKET_NAME_CMMB_SIM_COMMAND);

        goto error;

    }

    //write command getimsi

    if(SmsMbbmsSimSocketWrite(fd, data, datasize) != datasize)

    {

        LOGE("Failed to write cmmand %d to socket: %s!!!!\n'", CMMB_REQUEST_GET_IMSI, SOCKET_NAME_CMMB_SIM_COMMAND);

        goto error;

    }

    //write end, start read response

    //read head, include length of data, 4 byte

    if(SmsMbbmsSimSocketRead(fd, response_data, 4) != 4)

    {

        LOGE("Failed to read response command %d 's length from socket: %s!!!!!\n'", CMMB_REQUEST_GET_IMSI, SOCKET_NAME_CMMB_SIM_COMMAND);

        goto error;

    }

    //LOGD("response_data of length: %d, %d, %d, %d!!!\n", response_data[0], response_data[1], response_data[2], response_data[3]);

    //calculate length

    response_length = ((response_data[0] & 0xff) << 24)

                    | ((response_data[1] & 0xff) << 16)

                    | ((response_data[2] & 0xff) << 8)

                    | (response_data[3] & 0xff);

    //LOGD("response_length = %d\n", response_length);

    //check length

    if(response_length == 0)

    {

        LOGE("response %d 's length from socket: %s is not right!!!!!\n'", CMMB_REQUEST_GET_IMSI, SOCKET_NAME_CMMB_SIM_COMMAND);

        goto error;

    }

...

这样就是实现了客户端和服务器之间的通信。
http://www.linuxidc.com/Linux/2012-07/65506.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: