android11 native binder writeFileDescriptor和readFileDescriptor的使用

本文通过一个具体的Binder通信案例,展示了服务端与客户端之间的交互过程。案例中详细解释了如何使用Binder进行文件描述符传递,并在服务端实现文件写入操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务端

#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>

#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>

#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>

using namespace android;
using namespace std;

enum BinderLibTestTranscationCode {
	BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
	BINDER_LIB_TEST_REGISTER_SERVER,
	BINDER_LIB_TEST_ADD_SERVER,
    BINDER_LIB_TEST_ADD_POLL_SERVER,
    BINDER_LIB_TEST_CALL_BACK,
    BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
    BINDER_LIB_TEST_DELAYED_CALL_BACK,
    BINDER_LIB_TEST_NOP_CALL_BACK,
    BINDER_LIB_TEST_GET_SELF_TRANSACTION,
    BINDER_LIB_TEST_GET_ID_TRANSACTION,
    BINDER_LIB_TEST_INDIRECT_TRANSACTION,
    BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
    BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
    BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
    BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
    BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
    BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
    BINDER_LIB_TEST_EXIT_TRANSACTION,
    BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
    BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
    BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
    BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
    BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
    BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
    BINDER_LIB_TEST_GETPID,
    BINDER_LIB_TEST_ECHO_VECTOR,
    BINDER_LIB_TEST_REJECT_BUF,
};

static String16 binderLibTestServiceName = String16("test.binderLib.0921");

class BinderLibTestService: public BBinder {
public:
	explicit BinderLibTestService(int32_t id)
			 {

	}
	~BinderLibTestService() {
		exit(EXIT_SUCCESS);
	}

	virtual status_t onTransact(uint32_t code, const Parcel &data,
			Parcel *reply, uint32_t flags = 0) override {
		printf("%s: code %d\n", __func__, code);
		switch (code) {
		  case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
		                int ret;
		                int fd;

		                fd = data.readFileDescriptor();
		                if (fd < 0) {
		                	printf("BAD_VALUE\n");
		                    return BAD_VALUE;
		                }
		                	char a[] = "hello,andy\n";
		                	ret = write(fd, a, strlen(a));
		                	printf("write:  %d\n",ret);
		                close(fd);
		            	printf("NO_ERROR\n");
		                return NO_ERROR;
		            }

		  case BINDER_LIB_TEST_NOP_CALL_BACK: {
		                Parcel data2, reply2;
		                sp<IBinder> binder;
		                binder = data.readStrongBinder();
		                if (binder == nullptr) {
		                    return BAD_VALUE;
		                }
		                data2.writeInt32(8888);
		                binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
		                return NO_ERROR;
		            }
		default:
			return UNKNOWN_TRANSACTION;
		};
	}
private:
};

int main(int argc, char **argv) {
	sp<IBinder>   m_server;
	ProcessState::self()->startThreadPool();
	printf("10\n");
	status_t ret;
	sp<IServiceManager> sm = defaultServiceManager();
	BinderLibTestService *testServicePtr;
	int index = 0;
	sp<BinderLibTestService> testService = new BinderLibTestService(index);
	printf("addService\n");
	ret = sm->addService(binderLibTestServiceName, testService);
	printf("end\n");
	IPCThreadState::self()->joinThreadPool();
	return 0;
}

客户端,调用 writeFileDescriptor

#include <utils/Trace.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <iostream>
#include <stdint.h>
#include <sys/types.h>
#include <set>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>

#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <android-base/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <poll.h>
#include <pthread.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <sys/wait.h>

#include <private/binder/binder_module.h>
#include <sys/epoll.h>
#include <sys/prctl.h>

using namespace android;
using namespace std;

enum BinderLibTestTranscationCode {
	BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
	BINDER_LIB_TEST_REGISTER_SERVER,
	BINDER_LIB_TEST_ADD_SERVER,
	BINDER_LIB_TEST_ADD_POLL_SERVER,
	BINDER_LIB_TEST_CALL_BACK,
	BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
	BINDER_LIB_TEST_DELAYED_CALL_BACK,
	BINDER_LIB_TEST_NOP_CALL_BACK,
	BINDER_LIB_TEST_GET_SELF_TRANSACTION,
	BINDER_LIB_TEST_GET_ID_TRANSACTION,
	BINDER_LIB_TEST_INDIRECT_TRANSACTION,
	BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
	BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
	BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
	BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
	BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
	BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION,
	BINDER_LIB_TEST_EXIT_TRANSACTION,
	BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
	BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
	BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
	BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
	BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
	BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
	BINDER_LIB_TEST_GETPID,
	BINDER_LIB_TEST_ECHO_VECTOR,
	BINDER_LIB_TEST_REJECT_BUF,
};

static String16 binderLibTestServiceName = String16("test.binderLib.0921");

class BinderLibTestCallBack: public BBinder {
public:
	BinderLibTestCallBack() :
			m_result(0) {
	}
	status_t getResult(void) {
		return m_result;
	}

private:
	virtual status_t onTransact(uint32_t code, const Parcel &data,
			Parcel *reply, uint32_t flags = 0) {
		(void) reply;
		(void) flags;
		switch (code) {
		case BINDER_LIB_TEST_CALL_BACK: {
			status_t status = data.readInt32();
			if (status != NO_ERROR) {
				m_result = status;
			}
			printf("cb: callback called\n");
			std::cout << "cb: " << m_result << std::endl;

			//   triggerEvent();
			return NO_ERROR;
		}

		default:
			return UNKNOWN_TRANSACTION;
		}
	}

	status_t m_result;
	const uint8_t *m_prev_end;
};

class TestDeathRecipient: public IBinder::DeathRecipient {
private:
	virtual void binderDied(const wp<IBinder> &who) {
		printf("binderDied\n");
	}
	;
};

void f() {
	int fd = open("/system/bin/files0", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
	if (fd < 0) {
		perror(NULL);
		return;
	}

	char a[] = "abcdef0123456\n";
	write(fd, a, strlen(a));
	close(fd);
}

int main(int argc, char **argv) {
	sp < IBinder > m_server;
	ProcessState::self()->startThreadPool();
	status_t ret;
	sp < IServiceManager > sm = defaultServiceManager();
	m_server = sm->getService(binderLibTestServiceName);
	sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
	ret = m_server->linkToDeath(testDeathRecipient);
	Parcel data, reply;
	int fd = open("/system/bin/files0", O_RDWR | O_CREAT | O_APPEND, S_IRWXU);
		if (fd < 0) {
			perror(NULL);
			return -1;
		}
	data.writeFileDescriptor(fd, true);
	ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data,
			&reply);
	std::cout << ret << std::endl;
	printf("end\n");
	IPCThreadState::self()->joinThreadPool();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值