使用 IdentifyLookup 在 iOS 中过滤短信
垃圾短信是一个长期存在、令人困扰的问题。本文将介绍如何阻止这些短信、设备端的检测以及整合动态的服务器检测等。
Apple 在 WWDC 2017(iOS 11) 推出了 IdentityLookup 框架,让开发者可以参与到过滤短信的过程中。在 iOS 14,Apple 新增了两种过滤类别:交易信息(Promotion)、推广信息(transaction)。在 WWDC 2022(iOS 16),针对这两种类别,Apple 新增了 12 种子类别,推广信息包括 9 种子类别:其他(Others)、财务(Finance)、订单(Orders)、提醒(Reminders)、健康(Health)、天气(Weather)、运营商(Carrier)、奖励(Rewards)、公共服务(PublicServices)。交易信息包括 3 种子类别:其他(Others)、优惠(Offers)、优惠券(Coupons)。
消息过滤流程
消息过滤通过应用程序扩展(App extension)来完成。当用户收到来自未知发件人的消息时,“消息” APP 通过询问 Message Filter Extension,来确定该消息的类别。Message Filter Extension 可以通过使用内置逻辑或推迟到关联服务器的分析来做出此决定。
IdentityLookup 仅适用于来自未知发件人的短信和彩信,它不适用于联系人列表中发件人的消息、不适用任何 iMessage 消息、不适用于回复发件人 3 次及以上的会话。
“消息” APP 使用一个 ILMessageFilterQueryRequest 对象将信息传递给 Message Filter Extension。Message Filter Extension 确定该消息的类别后,将 ILMessageFilterQueryResponse 对象返回给“消息” APP。
如果 App extension 无法自行做出决策,“消息” APP将会把有关信息发送到与 Message Filter Extension 关联的服务器,并将响应传递给 Message Filter Extension。Message Filter Extension 解析服务器的响应并返回最终的 ILMessageFilterQueryResponse 对象,如下图所示。
出于隐私原因,系统会处理与关联的服务器的所有通信;Message Filter Extension 无法直接访问网络,也无法将数据写入应用的共享容器中。
消息过滤实践
为 APP 新增 Message Filter Extension:
我们依次来看 MessageFilterExtension.swift
文件中的代码:
import IdentityLookup
final class MessageFilterExtension: ILMessageFilterExtension {}
ILMessageFilterExtension
是的主要类的抽象基类。在 Info.plist
中被设置 NSExtensionPrincipalClass
,将在收到消息时被构造:
ILMessageFilterExtension
类无其他要求或限制:
open class ILMessageFilterExtension : NSObject {
}
MessageFilterExtension
实现了 ILMessageFilterQueryHandling
、ILMessageFilterCapabilitiesQueryHandling
协议:
extension MessageFilterExtension: ILMessageFilterQueryHandling, ILMessageFilterCapabilitiesQueryHandling {
// ...
}
ILMessageFilterQueryHandling
ILMessageFilterExtension
子类必须符合 ILMessageFilterQueryHandling
协议,通过包含短信信息的 queryRequest
、提供请求关联网络服务器能力的 context
,来进行短信类别的判断。最终返回提供包含类别信息的 response
:
@available(iOS 11.0, *)
public protocol ILMessageFilterQueryHandling : NSObjectProtocol {
// 闭包
func handle(_ queryRequest: ILMessageFilterQueryRequest,
context: ILMessageFilterExtensionContext,
completion: @escaping (ILMessageFilterQueryResponse) -> Void)
// 异步函数
func handle(_ queryRequest: ILMessageFilterQueryRequest,
context: ILMessageFilterExtensionContext
) async -> ILMessageFilterQueryResponse
}
queryRequest
的信息如下,包括发件人号码 sender
、短信内容 messageBody
、ISO 国家代码 receiverISOCountryCode
:
@available(iOS 11.0, *)
open class ILMessageFilterQueryRequest : NSObject, NSSecureCoding {
open var sender: String? { get }
open var messageBody: String? { get }
@available(iOS 16.0, *)
open var receiverISOCountryCode: String? { get }
}
context
提供请求关联网络服务器能力,我们也只能使用该能力访问网络:
@available(iOS 11.0, *)
open class ILMessageFilterExtensionContext : NSExtensionContext {
// 闭包
open func deferQueryRequestToNetwork(completion: @escaping (ILNetworkResponse?, Error?) -> Void)
// 异步函数
open func deferQueryRequestToNetwork() async throws -> ILNetworkResponse
}
URL 记录在
Info.plist
的ILMessageFilterExtensionNetworkURL
中,无法进行自定义。
response
定义如下,需要提供对应的类别和子类别:
@available(iOS 11.0, *)
open class ILMessageFilterQueryResponse : NSObject, NSSecureCoding {
open var action: ILMessageFilterAction
@available(iOS 16.0, *)
open var subAction: ILMessageFilterSubAction
}
即 none
、allow
、junk
、 promotion
、 transaction
类别,none
与allow
的行为相同:
@available(iOS 11.0, *)
public enum ILMessageFilterAction : Int, @unchecked Sendable {
case none = 0
case allow = 1
case junk = 2
@available(iOS 14.0, *)
case promotion = 3
@available(iOS 14.0, *)
case transaction = 4
}
以及文章开头提到的 12 种子类别:
@available(iOS 16.0, *)
public enum ILMessageFilterSubAction : Int, @unchecked Sendable {
case none = 0
/// TRANSACTIONAL SUB-ACTIONS
case transactionalOthers = 10000
case transactionalFinance = 10001
case transactionalOrders = 10002
case transactionalReminders = 10003
case transactionalHealth = 10004
case transactionalWeather = 10005
case transactionalCarrier = 10006
case transactionalRewards = 10007
case transactionalPublicServices = 10008
/// PROMOTIONAL SUB-ACTIONS
case promotionalOffers = 20001
case promotionalCoupons = 20002
}
因此,整体的过滤代码框架如下,依次进行设备端的检测、服务器检测:
func handle(_ queryRequest: ILMessageFilterQueryRequest,
context: ILMessageFilterExtensionContext,
completion: @escaping (ILMessageFilterQueryResponse) -> Void
) {
// 设备端的检测
let (offlineAction, offlineSubAction) = self.offlineAction(for: queryRequest)
switch offlineAction {
case .allow, .junk, .promotion, .transaction:
let response = ILMessageFilterQueryResponse()
response.action = offlineAction
response.subAction = offlineSubAction
completion(response)
case .none:
// 服务器检测
context.deferQueryRequestToNetwork() { (networkResponse, error) in
let response = ILMessageFilterQueryResponse()
if let networkResponse = networkResponse {
(response.action, response.subAction) = self.networkAction(for: networkResponse)
}
completion(response)
}
@unknown default:
break
}
}
这里需要注意,Apple 定义了服务器检测网络请求的格式,开发者无法进行自定义:
POST /server-endpoint HTTP/1.1
Accept: */*
Content-Type: application/json; charset=utf-8
Content-Length: 148
{
"_version": 1,
"query": {
"sender": "14085550001",
"message": {
"text": "This is a message"
}
},
"app": {
"version": "1.1"
}
}
ILMessageFilterCapabilitiesQueryHandling
ILMessageFilterCapabilitiesQueryHandling
协议会更简单些:
@available(iOS 16.0, *)
public protocol ILMessageFilterCapabilitiesQueryHandling : NSObjectProtocol {
// 闭包
func handle(_ capabilitiesQueryRequest: ILMessageFilterCapabilitiesQueryRequest,
context: ILMessageFilterExtensionContext,
completion: @escaping (ILMessageFilterCapabilitiesQueryResponse
) -> Void)
// 异步函数
func handle(_ capabilitiesQueryRequest: ILMessageFilterCapabilitiesQueryRequest,
context: ILMessageFilterExtensionContext
) async -> ILMessageFilterCapabilitiesQueryResponse
}
其中,capabilitiesQueryRequest
无实际含义,context
同前文。需要提供的是 ILMessageFilterCapabilitiesQueryResponse
:
@available(iOS 16.0, *)
open class ILMessageFilterCapabilitiesQueryResponse : NSObject, NSSecureCoding {
}
@available(iOS 16.0, *)
@available(macOS, unavailable)
extension ILMessageFilterCapabilitiesQueryResponse {
@nonobjc final public var transactionalSubActions: [ILMessageFilterSubAction]
final public var promotionalSubActions: [ILMessageFilterSubAction]
}
指定了 Message Filter Extension 可以显示的子类别。我们可以这样展示以显示子类别:
func handle(_ capabilitiesQueryRequest: ILMessageFilterCapabilitiesQueryRequest,
context: ILMessageFilterExtensionContext,
completion: @escaping (ILMessageFilterCapabilitiesQueryResponse) -> Void
) {
let response = ILMessageFilterCapabilitiesQueryResponse()
response.transactionalSubActions = [ .transactionalOthers, .transactionalFinance, .transactionalOrders, .transactionalReminders, .transactionalHealth, .transactionalWeather, .transactionalCarrier, .transactionalRewards, .transactionalPublicServices ]
response.promotionalSubActions = [ .promotionalOthers, .promotionalOffers, .promotionalCoupons, ]
completion(response)
}
在 iOS16 设备上,不同配置样式如下:
未配置短信过滤 | 配置短信过滤,无子类别 | 配置短信过滤,展示所有子类别 |
垃圾短信和垃圾电话上报
此外,我们可以一个 App Extension,让用户将不需要的短信和电话上报为垃圾内容。上报电话需要用户在最近列表中进行左滑后选择报告。对于在消息记录中的短信,用户可以按下报告垃圾信息按钮:
创建 Unwanted Communication Reporting Extension:
我们可以看到模版代码十分简单:
class UnwantedCommunicationReportingExtension: ILClassificationUIExtensionViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Notify the system when you have completed gathering information
// from the user and you are ready with a classification response
self.extensionContext.isReadyForClassificationResponse = true
}
// Customize UI based on the classification request before the view is loaded
override func prepare(for classificationRequest: ILClassificationRequest) {
// Configure your views for the classification request
}
// Provide a classification response for the classification request
override func classificationResponse(for request:ILClassificationRequest) -> ILClassificationResponse {
return ILClassificationResponse(action: .reportJunk)
}
}
当用户上报时,系统会启动 App Extension。搜集用户外信息后,进行后续的上报或阻止,如下图所示。
具体来说,系统会依次:
- 实例化 App Extension 中的 ILClassificationUIExtensionViewController 子类。
- 调用实例的 prepare(for:)`方法并将控制器呈现给用户。
- 使用实例从用户那里收集数据,搜集完成 isReadyForClassificationResponse 设置为
true
。 - 如果用户按下取消按钮,系统将关闭
ILClassificationUIExtensionViewController
子类实例。
- 如果用户按下完成,系统将调用 classificationResponse(for:) 方法,传入一个 ILClassificationRequest 对象。
- 系统根据方法的 ILClassificationResponse 响应采取不同的操作。
@available(iOS 12.0, *)
open class ILClassificationResponse : NSObject, NSSecureCoding {
open var action: ILClassificationAction { get }
@available(iOS 12.1, *)
open var userString: String?
open var userInfo: [String : Any]?
public init(action: ILClassificationAction)
}
ILClassificationAction
类型为:
/// Describes various classification actions.
@available(iOS 12.0, *)
public enum ILClassificationAction : Int, @unchecked Sendable {
/// Indicate that no action is requested.
case none = 0
/// Report communication(s) as not junk.
case reportNotJunk = 1
/// Report communication(s) as junk.
case reportJunk = 2
/// Report communication(s) as junk and block the sender.
case reportJunkAndBlockSender = 3
}
对于 ILClassificationAction.none
,系统会关闭视图控制器,但不会采取任何其他操作。
对于 ILClassificationAction.reportNotJunk
或 ILClassificationAction.reportJunk
,系统会根据 userInfo 属性生成报告,然后将其发布到扩展程序的 Info.plist 文件中指定的服务端(ILClassificationExtensionNetworkReportDestination)或者使用短信发到对应的号码(ILClassificationExtensionSMSReportDestination)。
对于 ILClassificationAction.reportJunkAndBlockSender
,系统的响应就像在 ILClassificationAction.reportJunk
操作中一样。 但是,在报告步骤之后,系统会发出提示,让用户知道该号码将被阻止(拉黑)。
最后,为了保护用户隐私,系统会在 App Extension 终止后删除该容器。有关详细信息,请参阅关于 iOS 文件系统。
参考资料
- SMS and Call Reporting
- SMS and MMS Message Filtering
- SMS and Call Reporting
- Filtering Unwanted Messages with Identity Lookup
- Explore SMS message filters
基于短信过滤能力。上线了喵喵消烦员 App:
喵喵消烦员是一款短信过滤工具软件。在如今信息爆炸的时代,您的隐私和安全由喵喵来守护!我们使用 scikit-learn,通过朴素贝叶斯算法对垃圾短信进行识别,通过 Core ML 将模型部署在本地,从而完成离线过滤任务。
- 隐私安全:我们不会索要任何位置、相机、通知、无线数据(网络)等权限,用户的数据不会被保存,同时也不可能被上传,所有操作均在本地完成。
- 高效精准:通过先进的算法技术,自动识别并过滤掉垃圾短信、诈骗信息、广告推销等不必要打扰的内容。
- 自定义设置:支持自定义关键词过滤,方便您针对个人需求进行个性化设置,避免不必要的干扰。
- 更新迭代:我们会通过版本升级定期更新过滤模型,确保始终能够准确地识别和拦截最新的垃圾短信和诈骗信息。
模型、App 还在不断调整和优化,欢迎使用和提供建议!
上一篇: 如何恢复小米手机上删除的短信?这里教你一个快速解决方案!
下一篇: 如何彻底删除短信 - 掘金
推荐阅读
-
使用 IdentifyLookup 在 iOS 中过滤短信
-
微信 "扫一扫 "物联网,全面揭秘 "扫一扫 "背后的扫盲技术!-1.1 扫一扫感知物体是做什么的? 1.1 微信扫一扫是做什么的? 扫一扫识物是指以图片或视频(商品图片:鞋/包/美妆/服饰/家电/玩具/图书/食品/珠宝/家具/其他商品)为输入媒介,挖掘微信内容生态中的有价值信息(电商+百科+资讯,如图1所示),并展示给用户。这里的电商基本涵盖了微信小程序覆盖上亿SKU的全量优质电商,可以支持用户货比N家并直接下单购买,百科和资讯则聚合了微信内的头部自媒体如搜狗、搜搜、百度等,向用户展示和分享拍摄商品相关的内容资讯。 图 1 扫一扫识别功能示意图 欢迎大家更新iOS新版微信→扫一扫→识货,亲自体验,也欢迎大家通过识货界面的反馈按钮向我们提交反馈意见。 扫一扫识物实景图展示 1.2 扫一扫识物有哪些使用场景? 扫一扫识物的目的是为用户访问微信内部生态内容开辟一个新窗口,以用户扫图片为输入形式,为用户提供微信生态内容中的百科、资讯、电商等作为展示页面。除了用户熟悉的扫一扫操作外,我们还将进一步拓展长按操作,让用户更方便地进行扫一扫操作。"扫一扫知事 "的落地场景主要涵盖三大部分: a. 科普知识: a.科普知识。用户通过扫一扫,可以在微信生态圈中获取该对象的百科、资讯等常识或趣闻,帮助用户更好地了解该对象; b.购物场景。同样的搜索功能支持用户看到喜欢的商品立即检索到微信小程序电商中的同款商品,支持用户即扫即购; c.广告场景。扫一扫识别物体可以辅助公众号文章、视频更好地理解其中蕴含的图片信息,从而更好地投放匹配广告,提高点击率。 1.3 Sweep Sense 为 Sweep 家族带来了哪些新技术? 对于扫一扫来说,大家耳熟能详的应该就是扫一扫二维码、扫一扫小程序码、扫一扫条形码、扫一扫翻译了。无论是各种形式的编码还是文字字符,都可以看作是图片的一种特定编码形式,而物的识别则是对自然场景图片的识别,这对于扫一扫家族来说是一个质的飞跃,我们希望从物的识别入手,进一步拓展扫一扫对自然场景图片的理解能力,比如扫酒、扫车、扫植物、扫人脸等服务,如下图3所示。 图 3 Sweep 家族
-
使用 hls.plugin 在 IOS H5 页面中无法正常播放 HLS 视频
-
iCloud 切换区域,中国区保留 appStore(更新)--自 2018 年 2 月 28 日起,中国区 iCloud 由云上贵州管理 苹果公司发布的公告 https://support.apple.com/zh-cn/HT208352 关键词 关键部分 受影响的 iCloud 账户:国家或地区设置为 "中国 "的 Apple ID。 iCloud 包含的服务照片、邮件、通讯录、日历、提醒事项、备忘、书签、钱包、钥匙串、云备份、云驱动器、应用程序数据 新条款和条件: 同意仅出于本协议允许的目的并在中国法律允许的范围内使用服务。 云桂洲在提供服务时应使用合理的技能并尽职尽责,但在适用法律允许的最大范围内,我们不保证或担保您通过本服务存储或访问的任何内容不会意外损坏、崩溃、丢失或根据本协议的条款被删除,如果发生此类损坏、崩溃、丢失或删除,我们不承担任何责任。您应自行负责维护您的信息和数据的适当备份。 Apple 和云上贵州有权访问您存储在服务中的所有数据,包括有权根据适用法律相互之间共享、交换和披露所有用户数据(包括内容)。 本协议的解释、效力和履行应适用*法律。对于因本协议引起的或与本协议有关的任何争议,云桂洲和您同意提交中国国际经济贸易仲裁委员会(CIETAC)根据提交仲裁时有效的法律在北京进行具有约束力的仲裁。 由云桂洲管理,用户选择: 停用; ID 到地区; 受 iCloud(由云桂洲运营)条款和条件约束 首先,我想说说我对数据安全的看法。 当我在朋友圈发布通知时,有些朋友回复说国外的操作并没有多安全,或者国外的安全只是相对于国外而言的等等。首先,我非常感谢这些朋友,这让我反思什么是数据安全。以下观点均属个人观点: 国外的月亮一定比国内圆? 这是一个根深蒂固的问题,只要有人说国外的东西比国内好,就会有人嘲笑崇洋媚外。我觉得我们在某些方面应该向国外学习,比如搜索引擎和版权问题。打开百度搜索 "数据安全",第一行肯定是广告。打开谷歌搜索 "数据安全",第一条就是 "数据安全_百度百科" .....各种版权问题大家都明白,支持正版,但不仅客户一心想找免费破解,就连作者也往往没有保护自己劳动成果或产品的想法。但从另一个层面来说,国内的发展和安全,甩国外几条街。没有说哪里好,哪里不好,辩证地去学习更好。 国外也有别有用心的数据泄露,谈何安全? 从加密解密的角度看,自古以来就没有绝对安全的加密,只有相对安全的做法。苹果的棱镜门、微软的 cpu 漏洞,各种参差不齐的被破解案例 ....是的,这的确是一个很好的论据,但凡事都不能只看一面,当年苹果面对FBI破解手机的要求,几经论证,苹果还是拒绝破解。这点拿到国内,只要上面的文件传达下去,还有企业敢说不吗?还敢说不吗? 关于这次iCloud数据迁移个人看法? 把数据迁移到贵州的云端,相当于把手机的所有数据都存储在贵州的云端服务器上。也许访问数据的速度会快很多,但我会把我的iCloud区放到美国,因为我不想数据存在云上贵州后经常接到莫名其妙的电话或短信,更不想因为乱用国外服务器而被请去喝茶。iCloud一个ID,即从中国账号转到美国区,主要用于数据存在美国服务器上。appStore一个ID,除了注册一个中国ID外,专门用来下载应用用,因为国外ID不支持酷狗和网易云等应用。麻烦的是,用了新的 appStore ID 后,当前的应用还得重新下载安装,因为旧的应用 ID 与新的应用 ID 不兼容,安装不了。最后,iCloud迁移后,国内用户使用美国服务器,估计要 "扶墙 "了。 专业步骤: 首先,进行appleID设置,这是前提条件,否则无法选择转移区域! 取消 appleID 的双重认证 取消家庭共享选项 二、窗口下载并安装 icloud 3.0 版
-
ios8.1.3完美越狱教程 ios8.4.1完美越狱工具-火凤凰在线越狱,设置->通用中选择可信软件。安装成功后使用软件进行越狱。 接下来就是打开SSH通道了。方法如下: 在 cydia 中安装 OpenSSH 和 Core Utilities 插件,安装完成后重启设备,然后使用越狱 APP 重新激活越狱。接下来,在 IceAssistant 中打开 SSH 通道。如果在这里找不到这两个插件,请自行百度 cydia 源空白。
-
windows下进程间通信的(13种方法)-摘 要 本文讨论了进程间通信与应用程序间通信的含义及相应的实现技术,并对这些技术的原理、特性等进行了深入的分析和比较。 ---- 关键词 信号 管道 消息队列 共享存储段 信号灯 远程过程调用 Socket套接字 MQSeries 1 引言 ---- 进程间通信的主要目的是实现同一计算机系统内部的相互协作的进程之间的数据共享与信息交换,由于这些进程处于同一软件和硬件环境下,利用操作系统提供的的编程接口,用户可以方便地在程序中实现这种通信;应用程序间通信的主要目的是实现不同计算机系统中的相互协作的应用程序之间的数据共享与信息交换,由于应用程序分别运行在不同计算机系统中,它们之间要通过网络之间的协议才能实现数据共享与信息交换。进程间通信和应用程序间通信及相应的实现技术有许多相同之处,也各有自己的特色。即使是同一类型的通信也有多种的实现方法,以适应不同情况的需要。 ---- 为了充分认识和掌握这两种通信及相应的实现技术,本文将就以下几个方面对这两种通信进行深入的讨论:问题的由来、解决问题的策略和方法、每种方法的工作原理和实现、每种实现方法的特点和适用的范围等。 2 进程间的通信及其实现技术 ---- 用户提交给计算机的任务最终都是通过一个个的进程来完成的。在一组并发进程中的任何两个进程之间,如果都不存在公共变量,则称该组进程为不相交的。在不相交的进程组中,每个进程都独立于其它进程,它的运行环境与顺序程序一样,而且它的运行环境也不为别的进程所改变。运行的结果是确定的,不会发生与时间相关的错误。 ---- 但是,在实际中,并发进程的各个进程之间并不是完全互相独立的,它们之间往往存在着相互制约的关系。进程之间的相互制约关系表现为两种方式: ---- (1) 间接相互制约:共享CPU ---- (2) 直接相互制约:竞争和协作 ---- 竞争——进程对共享资源的竞争。为保证进程互斥地访问共享资源,各进程必须互斥地进入各自的临界段。 ---- 协作——进程之间交换数据。为完成一个共同任务而同时运行的一组进程称为同组进程,它们之间必须交换数据,以达到协作完成任务的目的,交换数据可以通知对方可以做某事或者委托对方做某事。 ---- 共享CPU问题由操作系统的进程调度来实现,进程间的竞争和协作由进程间的通信来完成。进程间的通信一般由操作系统提供编程接口,由程序员在程序中实现。UNIX在这个方面可以说最具特色,它提供了一整套进程间的数据共享与信息交换的处理方法——进程通信机制(IPC)。因此,我们就以UNIX为例来分析进程间通信的各种实现技术。 ---- 在UNIX中,文件(File)、信号(Signal)、无名管道(Unnamed Pipes)、有名管道(FIFOs)是传统IPC功能;新的IPC功能包括消息队列(Message queues)、共享存储段(Shared memory segment)和信号灯(Semapores)。 ---- (1) 信号 ---- 信号机制是UNIX为进程中断处理而设置的。它只是一组预定义的值,因此不能用于信息交换,仅用于进程中断控制。例如在发生浮点错、非法内存访问、执行无效指令、某些按键(如ctrl-c、del等)等都会产生一个信号,操作系统就会调用有关的系统调用或用户定义的处理过程来处理。 ---- 信号处理的系统调用是signal,调用形式是: ---- signal(signalno,action) ---- 其中,signalno是规定信号编号的值,action指明当特定的信号发生时所执行的动作。 ---- (2) 无名管道和有名管道 ---- 无名管道实际上是内存中的一个临时存储区,它由系统安全控制,并且独立于创建它的进程的内存区。管道对数据采用先进先出方式管理,并严格按顺序操作,例如不能对管道进行搜索,管道中的信息只能读一次。 ---- 无名管道只能用于两个相互协作的进程之间的通信,并且访问无名管道的进程必须有共同的祖先。 ---- 系统提供了许多标准管道库函数,如: pipe——打开一个可以读写的管道; close——关闭相应的管道; read——从管道中读取字符; write——向管道中写入字符; ---- 有名管道的操作和无名管道类似,不同的地方在于使用有名管道的进程不需要具有共同的祖先,其它进程,只要知道该管道的名字,就可以访问它。管道非常适合进程之间快速交换信息。 ---- (3) 消息队列(MQ) ---- 消息队列是内存中独立于生成它的进程的一段存储区,一旦创建消息队列,任何进程,只要具有正确的的访问权限,都可以访问消息队列,消息队列非常适合于在进程间交换短信息。 ---- 消息队列的每条消息由类型编号来分类,这样接收进程可以选择读取特定的消息类型——这一点与管道不同。消息队列在创建后将一直存在,直到使用msgctl系统调用或iqcrm -q命令删除它为止。 ---- 系统提供了许多有关创建、使用和管理消息队列的系统调用,如: ---- int msgget(key,flag)——创建一个具有flag权限的MQ及其相应的结构,并返回一个唯一的正整数msqid(MQ的标识符); ---- int msgsnd(msqid,msgp,msgsz,msgtyp,flag)——向队列中发送信息; ---- int msgrcv(msqid,cmd,buf)——从队列中接收信息; ---- int msgctl(msqid,cmd,buf)——对MQ的控制操作; ---- (4) 共享存储段(SM) ---- 共享存储段是主存的一部分,它由一个或多个独立的进程共享。各进程的数据段与共享存储段相关联,对每个进程来说,共享存储段有不同的虚拟地址。系统提供的有关SM的系统调用有: ---- int shmget(key,size,flag)——创建大小为size的SM段,其相应的数据结构名为key,并返回共享内存区的标识符shmid; ---- char shmat(shmid,address,flag)——将当前进程数据段的地址赋给shmget所返回的名为shmid的SM段; ---- int shmdr(address)——从进程地址空间删除SM段; ---- int shmctl (shmid,cmd,buf)——对SM的控制操作; ---- SM的大小只受主存限制,SM段的访问及进程间的信息交换可以通过同步读写来完成。同步通常由信号灯来实现。SM非常适合进程之间大量数据的共享。 ---- (5) 信号灯 ---- 在UNIX中,信号灯是一组进程共享的数据结构,当几个进程竞争同一资源时(文件、共享内存或消息队列等),它们的操作便由信号灯来同步,以防止互相干扰。 ---- 信号灯保证了某一时刻只有一个进程访问某一临界资源,所有请求该资源的其它进程都将被挂起,一旦该资源得到释放,系统才允许其它进程访问该资源。信号灯通常配对使用,以便实现资源的加锁和解锁。 ---- 进程间通信的实现技术的特点是:操作系统提供实现机制和编程接口,由用户在程序中实现,保证进程间可以进行快速的信息交换和大量数据的共享。但是,上述方式主要适合在同一台计算机系统内部的进程之间的通信。 3 应用程序间的通信及其实现技术 ---- 同进程之间的相互制约一样,不同的应用程序之间也存在竞争和协作的关系。UNIX操作系统也提供一些可用于应用程序之间实现数据共享与信息交换的编程接口,程序员可以通过自己编程来实现。如远程过程调用和基于TCP/IP协议的套接字(Socket)编程。但是,相对普通程序员来说,它们涉及的技术比较深,编程也比较复杂,实现起来困难较大。 ---- 于是,一种新的技术应运而生——通过将有关通信的细节完全掩盖在某个独立软件内部,即底层的通讯工作和相应的维护管理工作由该软件内部来实现,用户只需要将通信任务提交给该软件去完成,而不必理会它的具体工作过程——这就是所谓的中间件技术。 ---- 我们在这里分别讨论这三种常用的应用程序间通信的实现技术——远程过程调用、会话编程技术和MQSeries消息队列技术。其中远程过程调用和会话编程属于比较低级的方式,程序员参与的程度较深,而MQSeries消息队列则属于比较高级的方式,即中间件方式,程序员参与的程度较浅。 ---- 4.1 远程过程调用(RPC)
-
在iOS中,使用CMPedometer获取行走步数:注意步数读数不可更改
-
南邮OJ Web任务大揭秘:层层挑战剖析 1. 挑战一:迷宫般的目录探索 题目作者似乎穷举了所有可能的目录组合,最终在404.php中的