CocoaAsyncSocketネットワーク通信で使用されるhttpプロトコルテスト(3)


CocoaAsyncSocketネットワーク通信で使用されるhttpプロトコルテスト(3)
前の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プロトコルフォーマット).
以下はエンコーダ/デコーダを実現する際に学習するURLです:(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
" 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
" 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