GCDAsyncSocketの簡単な使用

6885 ワード

第一部分:GcDAsyncSocketの一例モードでの作成
プロジェクトにはsocket長接続が1つしか存在しないため、単一の例モードで作成および使用できます.次のコード:SocketManager.h
#import 
#import "GCDAsyncSocket.h"

/*
 *block               ,          
 */
typedef void(^SocketReturnMessage)(NSString *message);

/*
 *        
 */
typedef void(^FaceCompareTaskBlock)(NSData *data,NSInteger tag,NSString *message,GCDAsyncSocket *socket);

/*
 *        
 */
typedef void(^DidDisconnectWithHostBlock)();

/*
 *GCDAsyncSocketDelegate GCDAsyncSocket     
 */
@interface SocketManager : NSObject

/*
 *  GCDAsyncSocket tcp socket  
 */
@property (nonatomic,strong) GCDAsyncSocket *socket;

/*
 *    
 */
@property (nonatomic,assign) NSUInteger port;

/*
 *  SocketReturnMessage   block  
 */
@property (nonatomic,copy) SocketReturnMessage socketMessageBlock;

/*
 *SocketReturnMessage  block   
 */
- (void)retumessageWithBlock:(SocketReturnMessage)socketMessageBlock;

/*
 *    
 */
@property(nonatomic,copy)FaceCompareTaskBlock faceCompareTask;
- (void)didFinishFaceCompareTaskWithBlock:(FaceCompareTaskBlock)faceCompareTask;

/*
 *  
 */
@property (nonatomic,copy)DidDisconnectWithHostBlock disconnectWithHost;
- (void)didDisconnectWithHostBlock:(DidDisconnectWithHostBlock)disconnectWithHost;


/*
 *     
 */
+ (SocketManager *)shareManager;

/*
 *    /     
 */
- (void)connectToHostWithPort:(NSUInteger)port;
@end

SocketManager.m
#import "SocketManager.h"

#define ConnectTime -1
@implementation SocketManager

#pragma mark      
+ (SocketManager *)shareManager
{
    static SocketManager *shareManager = nil;
    static dispatch_once_t onecToken;
    dispatch_once(&onecToken, ^{
        shareManager = [[SocketManager alloc]init];
    });
    return shareManager;
}

#pragma mark     
- (void)connectToHostWithPort:(NSUInteger)port
{
    if (self.socket == nil || [self.socket isDisconnected])
    {
        self.socket = [[GCDAsyncSocket alloc]init];
    }
    self.socket.delegate = self;
    self.socket.delegateQueue = dispatch_get_main_queue();
    NSError *error = nil;
    BOOL isConnectHost = [self.socket connectToHost:@"***.***.***.***"
                                             onPort:(uint16_t)port
                                        withTimeout:ConnectTime
                                            error:&error];
    if (isConnectHost == NO)//        
    {
        NSLog(@"ERROR:%@",error.description);
    }
}

#pragma mark        
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSString *message = [NSString stringWithFormat:@"DidConnectToHost.Host:%@--Port:%hu",host,port];
    self.socketMessageBlock(message);
}

#pragma mark     ,         
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    NSString *message = [NSString stringWithFormat:@"SocketDidDisconnect.ERROR:%@
",err.description]; self.socketMessageBlock(message); self.disconnectWithHost(); //TODO: } #pragma mark - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { NSString *message = [NSString stringWithFormat:@"DidAcceptNewSocket:%@",newSocket]; self.socketMessageBlock(message); } #pragma mark - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { [sock readDataWithTimeout:-1 tag:0]; NSString *message = [NSData dataWithGBKEncodingOfData:data]; self.socketMessageBlock(message); self.faceCompareTask(data, tag, message, sock); } #pragma mark - (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag { NSString *message = [NSString stringWithFormat:@"DidReadPartialDataOfLength:%lu",(unsigned long)partialLength]; self.socketMessageBlock(message); } #pragma mark - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { NSString *message = [NSString stringWithFormat:@"DidWriteDataWithTag:%ld",tag]; self.socketMessageBlock(message); } - (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag { NSString *message = [NSString stringWithFormat:@"DidWritePartialDataOfLength:%lu",(unsigned long)partialLength]; self.socketMessageBlock(message); } - (void)retumessageWithBlock:(SocketReturnMessage)socketMessageBlock { self.socketMessageBlock = socketMessageBlock; } - (void)didFinishFaceCompareTaskWithBlock:(FaceCompareTaskBlock)faceCompareTask { self.faceCompareTask = faceCompareTask; } - (void)didDisconnectWithHostBlock:(DidDisconnectWithHostBlock)disconnectWithHost { self.disconnectWithHost = disconnectWithHost; }

説明:
1.タイムアウト時間を-1に設定し、目的のデータを取得した後、手動で接続を切断するまで接続を維持できます.2.connectToHostWithPort :メソッドを抽出したのは、切断後に再接続するのを容易にするためです.
第2部:GcDAsyncSocketの使用
SOcketを使用するときにパッチデータを使用したので、第2部ではOCのdata回転byte[] について説明します.
1.data回転byte[]
NSData *data = UIImageJPEGRepresentation(faceImg, 1.0);
Byte *imageBytes = (Byte *)[data bytes ];

2.接合データの追加
接合データを追加する際には,主にNSMutableDataクラスの- (void)appendData:(NSData *)other;メソッドが用いられる.例を挙げると、次のようになります.
[responseBytes appendData:[NSData dataWithBytes:cardNumberBytes length:cardNumberLength]];

responseBytesはNSMutableDataクラスのオブジェクトで、cardNumberLengthはデータの長さです.
3.socketにおける大端バイト順と小端バイト順の問題
大端バイト順と小端バイト順の問題については、大端小端の意味(大端と小端の解釈付)を簡単に覚え、大端モードと小端モードを詳しく理解します.次に、私のプロジェクトで使用している変換サイズ端の方法を見てみましょう.
+ (char *)toLittleBytesWithInt:(int)length buffer:(char *)buffer
{
    for (int i = 0; i < 4; i++)
    {
        buffer[i] = (UInt8)0xff;
    }
    buffer[0] = (UInt8)(length       & 0xff);
    buffer[1] = (UInt8)(length >> 8  & 0xff);
    buffer[2] = (UInt8)(length >> 16 & 0xff);
    buffer[3] = (UInt8)(length >> 24 & 0xff);
    return buffer;
}
+ (int) fromLittleBytesWithBytes:(unsigned char*) pdata{
    int ndata3 = pdata[3] << 24;
    int ndata2 = pdata[2] << 16;
    int ndata1 = pdata[1] <<  8;
    int ndata0 = pdata[0] ;
    int nlenght = ndata3 + ndata2 + ndata1 + ndata0;
    return nlenght;
}

4.サーバへのデータの送信とサーバからのデータの読み出し
[self.manager.socket writeData:responseBytes withTimeout:-1 tag:0];
[self.manager.socket readDataToLength:4 withTimeout:-1 tag:0];
//         
[self.manager didFinishFaceCompareTaskWithBlock:^(NSData *data, NSInteger tag, NSString *message, GCDAsyncSocket *socket) {

}];

私もsocketを一歩一歩接続して使っていますが、足りないところがあれば、よろしくお願いします.