CocoaAsyncSocket 网络通信使用之http协议测试(三)

CocoaAsyncSocket
网络通信使用之http协议测试(三)

通过前一篇CocoaAsyncSocket网络通信使用之数据编码和解码(二),我们已经搭建好了socket的框架。

框架主要分为以下5个模块:

1-网络连接模块(socket connection)

2-数据协议框架(socket packet content protocol)

3-发送数据前的编码模块(socket encoder protocol)

4-接收数据后的解码模块(socket decoder protocol)

5-各模块的组合调用(socket service)

简述:

通过5个模块的协同工作,可以方便的处理tcp通信的扩展。

因为不方便公开外网服务,不能很好的测试自定义协议的编码器/解码器,

只是简单的对网络连接成功做了打印,现在我们来实践下框架的扩展用法。

http(HyperText Transport Protocol,超文本传输协议)

其实现在网上随处可见http协议的服务,而http是基于tcp/ip的,我们正好可以借用http来实践我们的用法。

现在就针对http协议来实现我们的编码器/解码器。

http协议内容很多,本文主要是测试sokcet框架,确认框架的完整性,拓展性,具体协议内容请自行搜索(http协议格式)。

以下是实现编码器/解码器时,学习的网址:(强烈建议学习一下,否则不好理解http编码器/解码器的内容哦)

http://blog.csdn.net/gueter/article/details/1524447

http协议的测试[编码器/解码器]

代码中只是测试用例,并非真实完整实现,看官勿喷。

RHPacketHttpRequest.h文件:(http协议的测试请求包)

#import "RHPacketBody.h"

@interface RHPacketHttpRequest : RHPacketBody

@property (nonatomic, copy) NSString *requestPath;
@property (nonatomic, copy) NSString *host;
@property (nonatomic, copy) NSString *connection;

@end

RHPacketHttpRequest.m文件:(只是测试,默认写了几个请求参数)

#import "RHPacketHttpRequest.h"

@implementation RHPacketHttpRequest

- (instancetype)init
{
    if (self = [super init]) {
        _requestPath = @"GET /index.html HTTP/1.1";
        _host = @"Host:www.baidu.com";
        _connection = @"Connection:close";
    }
    return self;
}

- (NSData *)data
{
    NSData *crlfData = [@"\r\n" dataUsingEncoding:NSASCIIStringEncoding];<span style="font-family: Arial, Helvetica, sans-serif;">//回车换行是http协议中每个字段的分隔符</span>

    NSMutableData *packetData = [[NSMutableData alloc] init];
    [packetData appendData:[_requestPath dataUsingEncoding:NSASCIIStringEncoding]];
    [packetData appendData:crlfData];
    [packetData appendData:[_host dataUsingEncoding:NSASCIIStringEncoding]];
    [packetData appendData:crlfData];
    [packetData appendData:[_connection dataUsingEncoding:NSASCIIStringEncoding]];
    [packetData appendData:crlfData];
//    [packetData appendData:[@"Accept:image/webp,*/*;q=0.8" dataUsingEncoding:NSASCIIStringEncoding]];
//    [packetData appendData:crlfData];
    return packetData;
}

@end

RHSocketHttpEncoder.h文件:(http协议的测试编码器)

#import <Foundation/Foundation.h>
#import "RHSocketEncoderProtocol.h"

@interface RHSocketHttpEncoder : NSObject <RHSocketEncoderProtocol>

@end

RHSocketHttpEncoder.m文件:

#import "RHSocketHttpEncoder.h"
#import "RHSocketConfig.h"

@implementation RHSocketHttpEncoder

- (void)encodePacket:(id<RHSocketPacketContent>)packet encoderOutput:(id<RHSocketEncoderOutputDelegate>)output
{
    NSData *data = [packet data];
    NSMutableData *sendData = [NSMutableData dataWithData:data];
    NSData *crlfData = [@"\r\n" dataUsingEncoding:NSASCIIStringEncoding];//回车换行是http协议中每个字段的分隔符,也是请求的结束符
    [sendData appendData:crlfData];

    NSTimeInterval timeout = [packet timeout];
    NSInteger tag = [packet tag];
    RHSocketLog(@"tag:%ld, timeout: %f, data: %@", (long)tag, timeout, sendData);
    [output didEncode:sendData timeout:timeout tag:tag];
}

@end

RHSocketHttpDecoder.h文件:(http协议的测试解码器)

#import <Foundation/Foundation.h>
#import "RHSocketDecoderProtocol.h"

@interface RHSocketHttpDecoder : NSObject <RHSocketDecoderProtocol>

@end

RHSocketHttpDecoder.m文件:

#import "RHSocketHttpDecoder.h"
#import "RHSocketConfig.h"
#import "RHPacketHttpResponse.h"

@interface RHSocketHttpDecoder ()
{
    NSMutableData *_receiveData;
}

@end

@implementation RHSocketHttpDecoder

- (NSUInteger)decodeData:(NSData *)data decoderOutput:(id<RHSocketDecoderOutputDelegate>)output tag:(long)tag
{
    @synchronized(self) {
        if (_receiveData) {
            [_receiveData appendData:data];
        } else {
            _receiveData = [NSMutableData dataWithData:data];
        }

        NSUInteger dataLen = _receiveData.length;
        NSInteger headIndex = 0;
        int crlfCount = 0;

        for (NSInteger i=0; i<dataLen; i++) {
            uint8_t byte;
            [_receiveData getBytes:&byte range:NSMakeRange(i, 1)];
            if (byte == 0x0a) {//0x0a是http协议中的字段分隔符,我们只是测试程序,简单解析对应返回数据,然后打印
                crlfCount++;
            }
            if (crlfCount == 2) {
                NSInteger packetLen = i - headIndex;
                NSData *packetData = [_receiveData subdataWithRange:NSMakeRange(headIndex, packetLen)];
                RHPacketHttpResponse *rsp = [[RHPacketHttpResponse alloc] initWithData:packetData];
                [output didDecode:rsp tag:0];
                headIndex = i + 1;
                crlfCount = 0;
            }
        }

        NSData *remainData = [_receiveData subdataWithRange:NSMakeRange(headIndex, dataLen-headIndex)];
        [_receiveData setData:remainData];

        return _receiveData.length;
    }//@synchronized
}

@end

测试调用方法:

    NSString *host = @"www.baidu.com";
    int port = 80;

    [RHSocketService sharedInstance].encoder = [[RHSocketHttpEncoder alloc] init];
    [RHSocketService sharedInstance].decoder = [[RHSocketHttpDecoder alloc] init];
    [[RHSocketService sharedInstance] startServiceWithHost:host port:port];

也可以继承RHSocketService对象,重载里面的接口方法,增加短线重连等等逻辑。

总结:

以上就是针对http协议实现的测试代码,我们可以看到,socket框架中的代码无需修改,完全可以共用。

这样以后即使是不同应用,不同的业务协议,也不需要重复造轮子了。

文章中都是以代码的方式呈现的,习惯看代码的同学可能比较易懂,但是缺乏整体框架的说明描述。

下一篇,针对当前的框架,绘制uml类图结构。

---------------------

转载请注明出处,谢谢

email: [email protected]

qq: 410289616

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 10:51:51

CocoaAsyncSocket 网络通信使用之http协议测试(三)的相关文章

一、网络通信模式和网络协议

分散式.集中式和分布式 在早期的计算机网络中,为了有效的利用计算机,一般讲数据通信模型分为分散式(Decentralized).集中式(Centralized)和分布式(Distributed). 1.分散式 在分散式系统中,用户只需要管理自己的计算机系统,各自独立的系统之间没有资源或信息的交换或共享.这种模型由于存在大量共享数据的重复存储,除了引起数据冗余之外,也很容易导致一个企业组织内各部门数据的不一致性,同时还会造成硬件,支持和运营维护等成本的大量增加,因此早淘汰. 2.集中式 在集中式环

CocoaAsyncSocket网络通信使用之tcp连接(一)

CocoaAsyncSocket网络通信使用之tcp连接(一) 简述: 在互联网世界中,网络访问是必不可少的一部分,而对于程序员来说,网络编程却是一个比较复杂的存在,特别是socket处理方面. 在android平台中,java类库丰富,封装良好,比如:mina,netty等等. 而在ios平台中,也有出名的socket库,CocoaAsyncSocket. 最近碰到一些朋友在socket的应用上一直不是特别熟悉,自己在接触过socket底层库,使用过mina,netty和CocoaAsyncS

CocoaAsyncSocket网络通信使用之数据编码和解码(二)

CocoaAsyncSocket网络通信使用之数据编码和解码(二) 在上一篇CocoaAsyncSocket网络通信使用之tcp连接(一)中,我们已经利用 CocoaAsyncSocket封装了自己的socket connection. 本篇主要是通过引入编码器和解码器,将可以共用的内容模块化. 简述: 在tcp的应用中,都是以二机制字节的形式来对数据做传输. 一般会针对业务协议构造对应的数据结构/数据对象,然后在使用的时候针对协议转换成二进制数据发送给服务端. 但是我们在不同的app中,不同的

TCP协议的三次握手+四次断开

TCP协议的三次握手 1.TCP/IP协议概述 TCP/IP协议(Transmission Control Protocol/Internet Protocol)叫做传输控制/网际协议,又叫网络通讯协议,这个协议是Internet国际互联网络的基础.TCP/IP是网络中使用的基本的通信协议.虽然从名字上看TCP/IP包括两个协议,传输控制协议(TCP)和网际协议(IP),但TCP/IP实际上是一组协议,它包括上百个各种功能的协议,如:远程登录.文件传输和电子邮件等,而TCP协议和IP协议是保证数

Andriod SDK和Loadrunner的HTTP协议测试环境搭建

Andriod SDK和Loadrunner的HTTP协议测试环境搭建 1.Andriod SDK安装 1.1 安装JDK(不累述) 1.2 配置环境变量 配置JDK的系统变量环境,我们需要设置三个系统变量,分别是JAVA_HOME,Path和CLASSPATH.下面是这三个变量的设置防范. JAVA_HOME 先设置这个系统变量名称,变量值为JDK在你电脑上的安装路径:C:\Program Files\Java\jdk1.8.0_20.创建好后则可以利用%JAVA_HOME%作为JDK安装目录

Android APP压力测试(三)之Monkey日志自动分析脚本

Android APP压力测试(三) 之Monkey日志自动分析脚本 前言 上次说要分享Monkey日志的分析脚本,这次贴出来分享一下,废话不多说,请看正文. [目录] 1.Monkey日志分析脚本 2.脚本原理 3.操作实例 1.Monkey日志分析脚本 1).脚本文件:Monkey_Log分析.bat @ECHO OFF ECHO.::::::::::::::::::::::::::::::::::::::::::::::::: ECHO.::             分析Monkey日志 

tcp/ip协议第三章 ip:网际协议

tcp/ip协议第三章读后总结 ip是tcp/ip协议族中最为核心的协议.ip提供不可靠传输,不可靠的意思是它不保证ip数据包能成功的到达目的地.ip仅提供最好的传输服务.任何要求的可靠性必须由上层来提供(如tcp) 子网的划分缩小了internet路由表的规模,因为许多网络经常可以通过单个表目就可以访问了. 接口网络的有关信息通过ifcongif和netstat命令可以获得,包括接口的ip地址.子网掩码.广播地址.以及mtu等

ONVIF协议测试工具的简单使用(一)

最近开始学习Onvif协议了.在这里记录下学习过程中的点点收获. ********************************************************** 一.检测局域网内的设备是否支持Onvif协议 1.安装ONVIF Test Tool 工具 我用的是Test_Tool_v13_06版本的.如果PC上没有装.NET Framework 3.5的话,会提示你先安装.NET Framework 3.5. 2.ONVIF Test Tool的使用 打开该软件,选择本机的

Tcpreplay让协议测试从此无忧

我是一枚在软件测试行业泡了7年的妹纸,想分享点自己的一些心得体会.在我刚接触协议测试那会,相当迷茫.过程中一系列的问题便不约而至,例如: ·如何明确入参出参? ·如何掌控流量? ·如何重现bug? ·如何模拟使用不常见协议的流量? ·如何模拟大数据量,进行性能和稳定性测试? 这么多问题,通过手工显然无法实现,一定要利用好工具,实现自动化测试.无疑对我这样一个菜鸟来说,是一个全新的挑战. 谈到网络协议,我们自然而然会想到Wireshark.tcpdump等抓包工具,而tcpreplay即是为它们而