在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 军事新闻 爱好者。
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 军事新闻 爱好者。
相关文章推荐
- 在Android上使用LocalSocket实现上层Java和底层C++的通信
- 在Android上使用LocalSocket实现上层Java和底层C++的通信
- Android中java层使用LocalSocket和底层进行通讯
- Android中java层使用LocalSocket和底层进行通讯
- Android中使用socket使底层和framework通信的实现方法
- Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView)
- Android Fk: PKMS(3)之installd及LocalSocket实现Java层与Native层通信
- Android中使用开源框架EventBus3.0实现Fragment之间的通信交互
- Mac下使用Eclipse实现Android中调用C/C++(NDK)基础详细教程
- Android下c++调用java实现内置外置sd卡MP3扫描并保存在文件中
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- AIDL/IPC Android AIDL/IPC 进程通信机制——超具体解说及使用方法案例剖析(播放器)
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android JNI(JNI(JAVA同C++配合使用)
- Android 开发过程中 Java 代码中属性 设置 底层实现
- 二、Cocos2dx中Android部分的c++和java实现相互调用(高级篇)
- 使用Broadcast实现android组件之间的通信
- Android中简单的JNI使用,C++调用JAVA
- 使用基于Android网络通信的OkHttp库实现Get和Post方式简单操作服务器JSON格式数据