情景:ios手机端A用usb线连接在另外一个嵌入式系统B上,B不能上网,要通过A完成代理上网功能。详情如:在B操作系统的浏览器上点击一个 “百度”的网页连接,我们的程序将利用MFI通过usb线,将该网页请求截获并发送到手机A上,手机A解析该网络请求,提取出IP地址和端口,利用手机上网,访问“百度”主页,并将服务器返回的内容,再用MFI通道回馈给B系统,让其呈现给用户,从而实现通过手机代理上网的功能。
任务:手机A接受到以截获的网络请求后,解析数据包,发送到指定的服务器,并获取返回内容,传送给系统B。
困惑: 在ios中如何解析网络传输的数据包? 如何区分出该包是tcp协议,还是udp协议? 如何从数据包中分离出,目的地址ip 和 端口号?
请各位老师,提示一二,本人对ios的文档也不太熟悉,对网络知识也很匮乏,不知道处理该网络编程的框架和库是用哪些,还望指点,谢谢!
第一个嘛,文档我也不熟,但我觉得一般iOS开发不会接触到这个层面的细节问题吧。除了第一个问题,其他都是跟报文格式相关。其实都可以通过对报文字段的提取获得。
5楼 @shifeng310 哦,那么貌似代码量不会很大,也不需要你去探测什么流量,就是你的设备要支持iPhone的Usb共享上网协议,这个我不太懂,你往这个方向寻找资料吧
不过,都要连iPhone了,而且需要流量的话,谁还用车载导航呢?
10楼 @Archfeed 我也想的跟你差不多,觉得不同的协议的报文格式不同,报文里包含了ip和端口,只要去解析报文应该能解决,可是我也不知道从哪里找文档啊。。。 而且网络上关于ios的网络编程都是应用层面了,没这么底层啊,没找到什么太多有价值的资料
从上面两点以及你的初步需求来看,你最好说明或者明确要针对哪种应用协议来进行代理,否则你要做的是就太复杂了。
假设只是针对http,你最好先找找有没有现成实现代理http的库,一个Back2Back Server:一端是客户端逻辑(像真正的服务器发出请求以及接受回复),一端是服务器逻辑(作为你的B设备的服务器,处理B的请求以及向B回复)。因为你这个应用不需要做任何数据处理(我假定),所以也就是一个restful服务器,仅仅做转发。
但这里有一个前提是,因为你的B是完全没有上网能力的设备(至少你没说明有),所以B不能直接通过设置网络代理的方式来通过A上网。如果你需要采用标准浏览器来访问,你必须修改B的网络核心层,估计这一步最难了,要改动到socket底层的实现,那么底层的部分我也没做过,估计你没有网络通讯开发经验更难。
我建议你最好采用自己修改过的浏览器,在浏览器核心中,把原来建立socket的逻辑全部修改为通过MFI(话说MFI是啥?)通讯。浏览器核心还是自己组装http请求和解释http回复。
因为是自己实现的通讯接口,所以协议可以自己定,大概把目标服务器IP/域名和端口,以及http请求数据一起传给A端;A端的APP处理这个自定义协议的数据,把http请求(根据需要做一定的数据修改,这里我不清楚会有什么需求)发到目标服务器;等待到回复后,除非你要做中间处理,否则基本上可以直接将http回复通过你的协议传回给B端。所以A上的APP其实不太需要对数据包进行处理(但这里只针对http来说,每种应用协议得单独分析)。
至于你问iOS如何解释网络数据包,这个问题还是得先清楚你问得是哪种协议,http的话iOS里面已经有封装,不需要你自己做,你只需要通过API来获取对应数据就可以了。如果是其他协议,例如smtp、sip之类的,得查查有没有系统支持(smtp应该有,sip不确定),没有就得找第三方库(自己实现协议栈其实很麻烦的,很少会这么干)。
上面回复的还是比较笼统,因为你的需求描述得相当不明确。
14楼 @nickel 感谢nickel如此认真的回复,上个星期临时去更改一个app的bug,增加新功能;则把这个网络代理的项目暂时搁浅了十天。看到你的回复真是倍感欣慰,而且内容对我帮助很大,因为刚接触ios 三个月,网络编程更是零经验所以很多地方我也不知道怎么用较为专业的语言来描述。 我现在是要做的最核心的一个功能是:从一个tcp、udp或icmp的数据包中,解析出我要的目标地址和端口号; 至于mfi(make for ipad,iphone,itouch) 是苹果手机和外界系统有线链接,传输数据的一种方式
如果要分析tcp/udp甚至icmp的包,你要用到比socket还下一层的底层通讯技术,这个你最好还是自己买书看看吧,我也不是很懂。另外,估计你用不了objc的oo层接口,得直接用c了,我相信一般框架都只提供socket以上的封装接口,socket以下应该需要自己用c来处理。
我只是怀疑,你是不是真的需要自己去处理socket一下的逻辑?!最好还是找高层封装的库,或者直接修改浏览器核心。你完全可以用自己的协议来把自定义的数据封装起来传输,然后到另一端后拆出再组装成标准协议继续处理,这样应该不需要去直接分析和处理tcp/udp的包。
socket就可以解析IP层的协议,不过看你是如何实现了。如果你就是做一HTTP代理,那相对容易些;如果你做的是个hook类的东西,把截到的包自己分析就累一些。网络编程我还有点经验,不过都是*unix下的,没在iOS下做过开发,只能给你些参考意见。
17楼 @nickel 是的今天找了几个资料,关于解析网络数据包的都是c语言写的了,还好在xcode的项目里面能够直接加载适用.c文件;了解了.pcap格式的网络数据包,但是目前还是不知道如何把ip地址,目标端口号从 tcp中解析出来,明天再查查资料
因为你现在做的是类似钩子的逻辑,把包给拦截然后处理,这就辛苦了。做代理模式比较简单,你最好往这边多研究一下,不要老是想着自己去拦截处理包,这是最笨最累的方法。