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

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

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

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

.....

 

           try {

                LocalServerSocket server = newLocalServerSocket(SOCKET_ADDRESS);

                while (true) {

                    //Log.i(TAG, "beginaccept");

                    LocalSocket receiver =server.accept();

                    if (receiver != null) {

                        InputStream input =receiver.getInputStream();

 

                        byte[] bytes = newbyte[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, ParcelparamParcel) 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(LocalSocketparamLocalSocket, 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, "receivedCMMB_REQUEST_GET_IMSI command!");

              /*

               * 唯一的用户ID:

               * 例如:IMSI(国际移动用户识别码) fora 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;

    }

    //writeend, 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 notright!!!!!\n'", CMMB_REQUEST_GET_IMSI, SOCKET_NAME_CMMB_SIM_COMMAND);

       goto error;

    }

...

 

这样就是实现了客户端和服务器之间的通信。

QQ 240136495

http://www.jsqj.cc 军事新闻 爱好者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐