IOS 笔记之 网络代理

本文介绍了在iOS应用中添加联通服务器代理以实现定向流量功能的过程。内容包括HTTP代理和TCP代理的实现细节,重点讲解了ASIHTTPRequest库如何设置代理以及自定义TCP代理协议的实现。建议开发者在进行此类开发时,深入理解网络模型并寻求有经验的同事协助。
摘要由CSDN通过智能技术生成

前一段时间做了一个功能:

在App内添加联通服务器代理,实现定向流量的功能。

成果如下:

这里添加的代理分两类:HTTP代理和TCP代理

(1)HTTP代理

对于HTTP代理,走的是HTTP标准代理协议,但是在IOS上面实现起来并不是那么简单,App内可能使用了多种封装的网络请求,还有一些第三方的类库,都不知道内部使用了什么方式联网,基于OC,大体分两种,一种是直接调用CFHTTP实现的;一种是基于系统封装类NSURLConnection实现的。

那么问题来了,基于系统封装类NSURLConnection实现的,是不提供接口设置代理的,尝试过各种方法,包括强行将代理塞入到Header中,或者使用NSURLProtocol拦截,都是无效的,所以使用此方式且不好修改的,就果断放弃吧。(典型代表:AFNetwork,MKNetwork)

对于直接使用CFHTTP实现的请求方式,属于较底层的实现方式,corefoundation是提供了添加代理接口的。(典型代表:ASIHTTPRequest)

最终,把联网请求修改成了ASI方式,虽然ASI已经停止更新,但是由于ASI的实现方式偏底层,非常稳定,并且便于深度定制自己的网络请求模块。

对于ASI的代理设置方式,很简单:

//设置代理
    if ([self shouldSetProxy]) {
        [request setProxyHost:"your host"];
        [request setProxyPort:8080];
        NSMutableDictionary * dic = [NSMutableDictionary dictionaryWithCapacity:2];
        [dic setObject:@"your value" forKey:@"Authorization"];
        [dic setObject:@"Keep-Alive" forKey:@"Proxy-Connection"];
        [request setRequestHeaders:dic];
    }

另外,对于ASI和AFN,这位兄弟分析的很好,感谢他:http://www.infoq.com/cn/articles/afn_vs_asi/

层次结构可以看一下:


(2)TCP代理

这个代理的设置比较有意思,或者说由于刚开始对于TCP/IP和SOCKET不熟悉,像没头苍蝇一样抓狂了好几天,有意思到想大喊一声:法克!

最终问题解决了,由于联通的TCP连接并不走标准sock5代理协议,只是按照格式发送一个数据流,也让我郁闷到想吐血。

首先通俗的介绍一下设置socket代理的原理:

socket是建立TCP连接的方式,三次握手之后,与代理服务器建立TCP连,接这是第一步。

此时,可以与代理服务器通信了,下面就是按照协议发送代理认证信息和目的服务器信息。如果采取sock5协议,需要先发送连接请求,查看服务器返回状态码,若需要验证,发送验证信息,若不需要验证或者验证通过,此时继续发送目的服务器相关信息。代码如下:

其中使用了第三方类库 GCDAsyncSocket

/**
 * Sends the SOCKS5 open/handshake/authentication data, and starts reading the response.
 * We attempt to gain anonymous access (no authentication).
 **/
- (void)socksOpen
{
    //XMPPLogTrace();
    
    //      +-----+-----------+---------+
    // NAME | VER | NMETHODS  | METHODS |
    //      +-----+-----------+---------+
    // SIZE |  1  |    1      | 1 - 255 |
    //      +-----+-----------+---------+
    //
    // Note: Size is in bytes
    //
    // Version    = 5 (for SOCKS5)
    // NumMethods = 1
    // Method     = 0 (No authentication, anonymous access)
    
    NSUInteger byteBufferLength = 3;
    uint8_t *byteBuffer = malloc(byteBufferLength * sizeof(uint8_t));
    
    uint8_t version = 5; // VER
    byteBuffer[0] = version;
    
    uint8_t numMethods = 1; // NMETHODS
    byteBuffer[1] = numMethods;
    
    uint8_t method = 0; // METHODS
    byteBuffer[2] = method;
    
    NSData *data = [NSData dataWithBytesNoCopy:byteBuffer length:byteBufferLength freeWhenDone:YES];
    DLog(@"TURNSocket: SOCKS_OPEN: %@", data);
    
    [asyncSocket writeData:data withTimeout:-1 tag:SOCKS_OPEN];
    
    //      +-----+--------+
    // NAME | VER | METHOD |
    //      +-----+--------+
    // SIZE |  1  |   1    |
    //      +-----+--------+
    //
    // Note: Size is in bytes
    //
    // Version = 5 (for SOCKS5)
    // Method  = 0 (No authentication, anonymous access)
    /* Method:
     o  X'00' NO AUTHENTICATION REQUIRED
     o  X'01' GSSAPI
     o  X'02' USERNAME/PASSWORD
     o  X'03' to X'7F' IANA ASSIGNE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值