文章目录
前言
一、Android 端可执行程序的 main 函数操作
二、Android 端 TCP 协议服务器建立
三、Android 端接收 PC 端传来的数据
四、博客资源
前言
本篇博客重点分析 Android 端 运行的远程命令工具 remote 模块 ;
该 Android 远程端模块 是 Android 平台的可执行程序 , 使用 NDK 进行编译的可执行程序 , 配合 PC 端的工具进行内存修改 ;
一、Android 端可执行程序的 main 函数操作
Android 端可执行程序主函数的主体就是一个死循环 , 在该循环中 , 通过 TCP 协议 , 接收来自 PC 端的指令 , 根据不同的指令 , 执行不同的操作 ;
开始执行后 , 阻塞等待 PC 端连接 , 连接成功后 , 继续向后执行 ;
/* 等待 PC 端连接 , PC 端与 Android 端连接成功后 , 继续向后执行 */ client.WaitForServer();
之后 , 还是阻塞等待 , 这次是等待 PC 端发送来的命令 ;
/* 等待 PC 端命令 */ client.WaitForCommand(root)
最后 , 根据获取的不同的命令 , 执行不同操作 , 这些操作 , 需要开发者自己进行开发 , 不同的应用 , 对应的操作也是不同的 ;
main 函数代码 :
int main() { /* Android 端可执行程序主函数的主体就是一个死循环 , * 在该循环中 , 通过 TCP 协议 , 接收来自 PC 端的指令 , * 根据不同的指令 , 执行不同的操作 */ do { Client client; char data[] = HELLO_INFO; const char* pinfo = "client prepare done! wait for pc! \n"; DECRYPT(data, pinfo); printf("%s\n", data); printf("%s", pinfo); /* 等待 PC 端连接 , PC 端与 Android 端连接成功后 , 继续向后执行 */ client.WaitForServer(); /* 连接成功提示 */ printf("get a connection!\n"); Json::Value root; do { /* 等待 PC 端命令 */ if (client.WaitForCommand(root) == 0) { switch (root["cmd"].asInt()) { case CMD_READ_DATA: root.clear(); client.ReadData(root); break; case CMD_WRITE_GOLD: client.WriteGold(root); break; case CMD_WRITE_EXP: client.WriteExp(root); break; default: break; } } /* 如果连接断开 , 那么重置连接 , 继续等待用户连接 */ else if (!client.isConnected()) { client.Reset(); printf("connection is lost!\nretry!\n"); break; } } while (client.isValid()); } while (1); return 0; }
Android 端可执行程序的 mian.c 代码位置 :
二、Android 端 TCP 协议服务器建立
从 TCP 网络协议角度看 , 在 Android 端运行的是 服务器端 , 在 PC 端运行的是 客户端 ;
Android 端的服务器建立 :
① 先绑定服务器 IP 地址 : 端口号
② 监听端口号
③ 阻塞等待客户端连接
PC 端的客户端 : 客户端只需要连接 绑定的服务器 IP 地址 + 端口号即可 ;
服务器建立代码 :
/* 建立服务器 * ① 先绑定服务器 IP 地址 : 端口号 * ② 监听端口号 * ③ 阻塞等待客户端连接 * 客户端只需要连接 绑定的服务器 IP 地址 + 端口号即可 */ bool WaitForServer() { int ret = 0; struct sockaddr_in addr, client; addr.sin_family = AF_INET; addr.sin_port = 0x3725;//0x2537=9527 /* 如果是 模拟器可以设置 127.0.0.1 , 如果是真机 , 需要填写局域网内真实 IP 地址 */ addr.sin_addr.s_addr = inet_addr("127.0.0.1"); /* 绑定 IP 地址 和 端口号 */ ret = bind(m_socket, (sockaddr*)&addr, sizeof(sockaddr_in)); if (ret < 0) { printf("error info:%d %s\n", errno, strerror(errno)); return false; } /* 监听端口号 */ ret = listen(m_socket, SOMAXCONN); if (ret < 0) { printf("error info:%d %s\n", errno, strerror(errno)); return false; } char buffer[4096] = ""; int size = sizeof(client); /* 阻塞等待客户端连接 */ int c = accept(m_socket, (sockaddr*)&client, &size); if (c == INVALID_SOCKET) { return false; } m_client = c; return ret >= 0; }
三、Android 端接收 PC 端传来的数据
调用 recv 方法 , 阻塞接收 PC 端传输来的数据 , 然后解析 json 字符串 , 将解析结果保存到 command 中 ;
代码如下 :
/* 接收 PC 端传输来的数据 * 然后解析 json 字符串 * 将解析结果保存到 command 中 */ int WaitForCommand(Json::Value& command) { char buffer[4096] = ""; int ret = recv(m_client, (void*)buffer, sizeof(buffer), 0); if (ret > 0) { ret = 0; Json::Reader reader; if (reader.parse(buffer, buffer + strlen(buffer), command)) { ret = 0; } else { ret = -1; } } else { close(m_client); m_client = INVALID_SOCKET; } return ret; }