iOS逆向进阶:iOS进程间通信方案深入探究与local socket介绍

news2024/11/25 7:16:32

在移动应用开发中,进程间通信(Inter-Process Communication,IPC)是一项至关重要的技术,用于不同应用之间的协作和数据共享。在iOS生态系统中,进程和线程是基本的概念,而进程间通信方案则为应用的功能拓展和性能优化提供了强大的支持。

1. 进程与线程:操作系统的核心概念

进程是指在操作系统中正在运行的一个独立程序实例。每个进程都拥有独立的内存空间,不同进程之间的数据隔离,通信需要特定的机制。在iOS中,每个应用运行在独立的进程中,这确保了应用之间的隔离性和稳定性。

线程是进程内的执行单元,一个进程可以包含多个线程。线程共享进程的内存空间,这使得它们可以更容易地共享数据。然而,多线程编程也带来了线程同步和竞态条件等复杂性问题。在iOS中,主线程通常处理UI交互,而后台线程执行耗时任务,以保持用户界面的响应性。

下面我们从代码角度讨论一下进程是如何被创建的:

1.1 Linux下进程的创建

在Linux下,可以使用C语言中的系统调用来创建新的进程。其中,fork()是一个常用的系统调用,用于创建一个新的进程,使得父进程和子进程可以并行运行。下面是一个简单的示例代码,展示了如何使用C语言在Linux下创建进程:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
    pid_t child_pid;

    // 创建新进程
    child_pid = fork();

    if (child_pid < 0) {
        fprintf(stderr, "Fork failed\n");
        return 1;
    } else if (child_pid == 0) {
        // 子进程执行的代码
        printf("This is the child process. PID: %d\n", getpid());
        // 子进程退出
        exit(0);
    } else {
        // 父进程执行的代码
        printf("This is the parent process. Child PID: %d\n", child_pid);
        // 等待子进程结束
        wait(NULL);
        printf("Child process has terminated.\n");
    }

    return 0;
}

在这个例子中,fork()会创建一个新的进程,其中子进程会从fork()返回处开始执行。在子进程中,我们打印子进程的PID,并使用exit(0)来退出子进程。在父进程中,我们打印子进程的PID,然后使用wait(NULL)来等待子进程结束。注意,父进程和子进程在内存空间中是独立的,但它们共享文件描述符等资源。

1.2 iOS中编译运行上述代码

在iOS平台上,你无法直接使用fork()来创建进程,因为iOS的应用程序在沙箱环境中运行,对于进程的管理和创建有一些限制。在iOS上,进程的创建和管理是由系统控制的,通常是由应用程序的主线程启动的。你可以正常编译运行,但尝试调用fork()函数会导致应用崩溃。

1.3 fork() 的底层原理

在这里插入图片描述

为了更好理解进程间通信,我们来介绍一下调用fork()时,操作系统的底层发生了哪些变化:

复制进程: 当一个进程调用fork()时,操作系统会创建一个新的进程,称为子进程。子进程是父进程的副本,包括了父进程的所有内存、文件描述符和其他资源。
复制内存空间: 子进程的地址空间会与父进程一样,但是子进程会获得一个独立的副本。这是通过"写时复制"(Copy-On-Write)机制实现的,意味着一开始父子进程共享内存,但如果任何一个进程修改了内存内容,操作系统会为修改的部分创建一个新的副本。
分配进程ID: 操作系统为子进程分配一个唯一的进程标识符(PID)。子进程的PID与父进程不同,但其它属性(如UID、GID等)可能会保持一致。
文件描述符的处理: 子进程会继承父进程的文件描述符。文件描述符是用于访问文件、套接字等I/O资源的句柄。子进程在继承文件描述符后,可以共享相同的文件或网络连接。
返回值: 在父进程中,fork()函数返回子进程的PID(正整数)。在子进程中,fork()函数返回0。如果fork()失败,返回值为负数,表示创建子进程失败。
继续执行: 父进程和子进程都从fork()调用之后的地方继续执行。由于子进程是父进程的副本,它们都从相同的代码位置开始运行。

其中可以特别注意一下"写时复制"的概念,这往往也是大厂面试重点考察的内容,如果感兴趣我们后续会展开介绍,可以关注本专栏以获取最新的文章。

2. iOS中的进程间通信方案

在iOS中,不同应用之间的数据共享和通信需要使用特定的进程间通信方案。以下是一些常见的iOS进程间通信方法:

**URL Scheme:**应用可以通过注册自定义的URL Scheme,在其他应用中通过URL调起目标应用,并传递数据。这通常用于简单的应用跳转和数据分享。
App Groups: App Groups 允许不同应用共享同一组容器目录,用于存储共享数据,如偏好设置和文件等。
Keychain Sharing: Keychain 是用于存储敏感数据的安全容器,应用可以在开发者账号下共享Keychain数据,实现跨应用的数据共享。
Notification: 应用可以使用通知中心发送和接收通知,实现应用间的消息传递。这适用于一对多的通信场景。
Local Socket: iOS进程间也可以通过本地socket方式进行通信,这是一个较为通用的方法,下面我们来详细介绍。

3. 使用Local Socket进行进程间通信

Local Socket 是一种基于网络套接字的进程间通信方法,适用于在同一台设备上的不同进程之间建立通信连接。下面是使用Local Socket进行进程间通信的简要示例代码:

进程1 - 发送数据

import Foundation

let serverURL = URL(fileURLWithPath: "/path/to/socket")
let socket = try! Socket.create(family: .unix, type: .stream, proto: .unix)
try! socket.connect(to: serverURL)

let dataToSend = "Hello, Process 2!".data(using: .utf8)!
try! socket.write(from: dataToSend)
socket.close()

进程2 - 接收数据

import Foundation

let serverURL = URL(fileURLWithPath: "/path/to/socket")
let socket = try! Socket.create(family: .unix, type: .stream, proto: .unix)
try! socket.bind(to: serverURL)
try! socket.listen(maxBacklogSize: 1)

let clientSocket = try! socket.acceptClientConnection()

var receivedData = Data()
_ = try! clientSocket.read(into: &receivedData)
let receivedString = String(data: receivedData, encoding: .utf8)
print("Received data: \(receivedString ?? "")")
clientSocket.close()

iOS进程间通信方案在不同场景下具有不同的优势和用途。我们应根据实际需求选择适合的通信方法,以实现应用之间的数据共享和协作,为用户提供更优质的体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/953392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行政固定资产应该怎么管理

行政需要管理的固定资产主要包括办公设备、交通工具、通讯设备、家具等。具体来说&#xff0c;行政需要管理的固定资产包括但不限于&#xff1a;电脑、打印机、传真机、复印机、投影仪、电话、传真机、传真纸、电话线、路由器、交换机、服务器、UPS电源、办公桌椅、沙发等。 行…

Java小项目【图书馆系统】

一、设计图书馆系统 Java是一个面向对象的语言&#xff0c;在编写代码的之前&#xff0c;我们要先确定有哪些对象 图书馆&#xff0c;首先有很多书&#xff0c;还有书架来放置这些书。然后是对书进行操作的人&#xff0c;比如普通用户和管理员。最后是对关于书的各种操作&#…

如何检测勒索软件攻击

什么是勒索软件 勒索软件又称勒索病毒&#xff0c;是一种特殊的恶意软件&#xff0c;又被归类为“阻断访问式攻击”&#xff08;denial-of-access attack&#xff09;&#xff0c;与其他病毒最大的不同在于攻击方法以及中毒方式。 攻击方法&#xff1a;攻击它采用技术手段限制…

软件系统第三方检测费标准

收费标准 软件系统第三方检测收费标准&#xff1a; 行业内对于第三方软件测试报告并没有一个明确的收费标准&#xff0c;不同地域之间的收费不同&#xff0c;各个检测单位的报价也略有差异。第三方检测报告的收费标准需要根据具体的测试需求而定&#xff0c;一般是按照项目大…

“算力+运力”扇动双翼,制造算力时代的蝴蝶效应

8月18日-20日&#xff0c;第二届中国算力大会在宁夏银川成功举办。 今年以来&#xff0c;随着大模型、AIGC等新技术的火爆&#xff0c;站在舞台中央的算力承载了无尽的期待&#xff0c;发展数字经济需要以算力基础设施为前提&#xff0c;社会各界已经形成了共识。 与此同时&…

一文速学-让神经网络不再神秘,一天速学神经网络基础(五)-最优化

前言 思索了很久到底要不要出深度学习内容&#xff0c;毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新&#xff0c;很多坑都没有填满&#xff0c;而且现在深度学习的文章和学习课程都十分的多&#xff0c;我考虑了很久决定还是得出神经网络系列文章&#xff0c;…

Kafka系列三基础概念

文章首发于个人博客&#xff0c;欢迎访问关注&#xff1a;https://www.lin2j.tech Kafka 是一款分布式消息发布和订阅系统&#xff0c;其高性能、高吞吐量的特点决定了其适用于大数据传输场景。 基础概念 Broker Broker 其实就是一个运行 Kafka 服务的服务器。Kafka 集群包…

chatGPT训练过程

强化学习基础 强化学习是指智能体在不确定环境中最大化其获得的奖励从而达到自主决策的目的。其执行过程为&#xff1a;智能体依据策略决策从而执行动作&#xff0c;然后感知环境获取环境的状态&#xff0c;进而得到奖励(以便下次再到相同状态时能采取更优的动作)&#xff0c;…

(java)进程和线程的联系和区别 。Java如何进行多线程编程?Thread 类及常见方法。

目录 进程 1.进程具有独立性 ———— 虚拟地址空间 线程 为什么要引入多个线程&#xff1f; 多线程注意点 ⁜⁜总结&#xff1a;线程和进程的区别和联系⁜⁜ &#xff08;经典面试题&#xff09; Java如何进行多线程编程&#xff1f; 创建线程 ——方法1 继承 Thre…

webrtc 的Bundle group 和RTCP-MUX

1&#xff0c;最近调试程序的时候发现抱一个错误 max-bundle configured but session description has no BUNDLE group 最后发现是一个参数设置错误 config.bundle_policy webrtc::PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle; 2&#xff0c;rtcp-mu…

SpringBoot项目,执行install命名时,控制台显示:Unable to find main class

构建springboot多模块项目&#xff0c;启动时可以正常启动&#xff0c;执行了父工程的maven的clean也没问题&#xff0c;执行install的时候就报错了&#xff1a;Unable to find main class。显而易见 这个错是找不到主类。 记录下解决过程&#xff1a; 首先看自己项目的父工程…

膦酸基官能团高盐环境下去除钙镁离子树脂

项目名称 某新能源公司除钙镁项目 工艺选择 串联运行 工艺原理 膦酸基官能团高盐环境下去除钙镁离子 项目背景 锂及其盐类是国民经济和国防建设中具有重要意义的战略物资&#xff0c;也是与人们生活息息相关的能源材料。而碳酸Li作为锂盐的基础盐&#xff0c;是制取锂化…

Matlab 基本教程

1 清空环境变量及命令 clear all % 清除Workspace 中的所有变量 clc % 清除Command Windows 中的所有命令 2 变量命令规则 &#xff08;1&#xff09;变量名长度不超过63位 &#xff08;2&#xff09;变量名以字母开头&#xff0c; 可以由字母、数字和下划线…

vue3路由跳转以及传参。和vue2路由跳转传参的区别

路由的安装和引入以及注册就不过多赘述&#xff0c;直接说区别和怎么跳转页面 vue2路由跳转以及传递参数 vue2只需要创建好router文件夹和index.js&#xff0c;配置好我们的路由&#xff0c;在main.js引入 import router from "/router"; // vue路由app.use(route…

如何避免重复消费消息

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

【函数栈帧解析:代码的迷人堆积和无限嵌套】

本章重点 一、何为函数栈帧 二、函数栈帧特性 - 同栈 - 后进先出 三、认识内存空间布局图 四、认识相关寄存器 五、认识相关汇编命令 六、测试代码&#xff1a; 七、函数栈帧全过程 要解决的问题​​​​​​​ 局部变量是怎么创建的&#xff1f;为什么局部变量的值是随机值&am…

10项必备的IT国际认证

10项必备国际IT认证对于希望在数字时代提升职业生涯的专业人士来说&#xff0c;已成为一项重要资产。 此类认证不仅肯定了你在特定IT领域的专业知识&#xff0c;还展现了你会在以后的生涯中不断学习和专业成长的决心。为了帮助你查询这些选择&#xff0c;我们编制了一份2023年…

华为OD机试 - 租车骑绿道 - 双指针(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路1、输入2、输出3、说明4、双指针算法 五、Java算法源码六、效果展示 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 部门组织绿岛骑行团建活动&#xff0c;租用公共双人自行车骑行&#xff0c;…

装箱、拆箱

装箱&#xff1a;将基本类型用它们对应的引用类型包装起来&#xff1b;拆箱&#xff1a;将包装类型转换为基本数据类型&#xff1b; Java 可以自动对基本数据类型和它们的包装类进行装箱和拆箱。 为什么要有包装器类型 因为java的三种集合&#xff0c;List、Set、Map&#xf…

【python零基础入门学习】python基础篇之判断与for循环(二)

本站以分享各种运维经验和运维所需要的技能为主 《python》&#xff1a;python零基础入门学习 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…