第2月第1天gcdasyncsocketdispatch_source_set_event_handler

lianhuaren lianhuaren     2022-08-15     687

关键词:

一、GCDAsyncSocket的核心就是dispatch_source_set_event_handler

1.accpet回调

            accept4Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket4FD, 0, socketQueue);
            
            int socketFD = socket4FD;
            dispatch_source_t acceptSource = accept4Source;
            
            dispatch_source_set_event_handler(accept4Source, ^{ @autoreleasepool {
                
                LogVerbose(@"event4Block");
                
                unsigned long i = 0;
                unsigned long numPendingConnections = dispatch_source_get_data(acceptSource);
                
                LogVerbose(@"numPendingConnections: %lu", numPendingConnections);
                
                while ([self doAccept:socketFD] && (++i < numPendingConnections));
            }});

 

2.read,write回调

 

    readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socketFD, 0, socketQueue);
    writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socketFD, 0, socketQueue);
    
    // Setup event handlers
    
    dispatch_source_set_event_handler(readSource, ^{ @autoreleasepool {
        
        LogVerbose(@"readEventBlock");
        
        socketFDBytesAvailable = dispatch_source_get_data(readSource);
        LogVerbose(@"socketFDBytesAvailable: %lu", socketFDBytesAvailable);
        
        if (socketFDBytesAvailable > 0)
            [self doReadData];
        else
            [self doReadEOF];
    }});
    
    dispatch_source_set_event_handler(writeSource, ^{ @autoreleasepool {
        
        LogVerbose(@"writeEventBlock");
        
        flags |= kSocketCanAcceptBytes;
        [self doWriteData];
    }});

二,缓存区

1.创建

GCDAsyncReadPacket没有传入buffer,则readpacket没有缓冲区,socket可读时会放入preBuffer

- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
{
    [self readDataToData:data withTimeout:timeout buffer:nil bufferOffset:0 maxLength:0 tag:tag];
}

- (void)readDataToData:(NSData *)data
           withTimeout:(NSTimeInterval)timeout
                buffer:(NSMutableData *)buffer
          bufferOffset:(NSUInteger)offset
                   tag:(long)tag
{
    [self readDataToData:data withTimeout:timeout buffer:buffer bufferOffset:offset maxLength:0 tag:tag];
}

- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(NSUInteger)length tag:(long)tag
{
    [self readDataToData:data withTimeout:timeout buffer:nil bufferOffset:0 maxLength:length tag:tag];
}

- (void)readDataToData:(NSData *)data
           withTimeout:(NSTimeInterval)timeout
                buffer:(NSMutableData *)buffer
          bufferOffset:(NSUInteger)offset
             maxLength:(NSUInteger)maxLength
                   tag:(long)tag
{
    if ([data length] == 0) {
        LogWarn(@"Cannot read: [data length] == 0");
        return;
    }
    if (offset > [buffer length]) {
        LogWarn(@"Cannot read: offset > [buffer length]");
        return;
    }
    if (maxLength > 0 && maxLength < [data length]) {
        LogWarn(@"Cannot read: maxLength > 0 && maxLength < [data length]");
        return;
    }
    
    GCDAsyncReadPacket *packet = [[GCDAsyncReadPacket alloc] initWithData:buffer
                                                              startOffset:offset
                                                                maxLength:maxLength
                                                                  timeout:timeout
                                                               readLength:0
                                                               terminator:data
                                                                      tag:tag];
    
    dispatch_async(socketQueue, ^{ @autoreleasepool {
        
        LogTrace();
        
        if ((flags & kSocketStarted) && !(flags & kForbidReadsWrites))
        {
            [readQueue addObject:packet];
            [self maybeDequeueRead];
        }
    }});
    
    // Do not rely on the block being run in order to release the packet,
    // as the queue might get released without the block completing.
}

 

 

三、面向对象封装

1.socket可读的时候先用preBuffer接收,拷贝到currentRead->buffer中,为生产者-消费者模式.

    GCDAsyncReadPacket *currentRead;
    GCDAsyncWritePacket *currentWrite;
    

    
    GCDAsyncSocketPreBuffer *preBuffer;

 

        uint8_t *buffer;
        
        if (readIntoPreBuffer)
        {
            [preBuffer ensureCapacityForWrite:bytesToRead];
                        
            buffer = [preBuffer writeBuffer];
        }

。。。

            int socketFD = (socket4FD == SOCKET_NULL) ? socket6FD : socket4FD;
            
            ssize_t result = read(socketFD, buffer, (size_t)bytesToRead);
            LogVerbose(@"read from socket = %i", (int)result);
            
。。。

                if (readIntoPreBuffer)
                {
                    // We just read a big chunk of data into the preBuffer
                    
                    [preBuffer didWrite:bytesRead];
                    LogVerbose(@"read data into preBuffer - preBuffer.length = %zu", [preBuffer availableBytes]);
                    
                    // Search for the terminating sequence
                    
                    bytesToRead = [currentRead readLengthForTermWithPreBuffer:preBuffer found:&done];
                    LogVerbose(@"copying %lu bytes from preBuffer", (unsigned long)bytesToRead);
                    
                    // Ensure there‘s room on the read packet‘s buffer
                    
                    [currentRead ensureCapacityForAdditionalDataOfLength:bytesToRead];
                    
                    // Copy bytes from prebuffer into read buffer
                    
                    uint8_t *readBuf = (uint8_t *)[currentRead->buffer mutableBytes] + currentRead->startOffset
                                                                                     + currentRead->bytesDone;
                    
                    memcpy(readBuf, [preBuffer readBuffer], bytesToRead);
                    
                    // Remove the copied bytes from the prebuffer
                    [preBuffer didRead:bytesToRead];
                    LogVerbose(@"preBuffer.length = %zu", [preBuffer availableBytes]);
                    
                    // Update totals
                    currentRead->bytesDone += bytesToRead;
                    totalBytesReadForCurrentRead += bytesToRead;
                    
                    // Our ‘done‘ variable was updated via the readLengthForTermWithPreBuffer:found: method above
                }

 

 

 

 

第26月第3天javagradle

1.430/Applications/AndroidStudio.app/Contents/gradle/gradle-2.8/bin/gradle-v434mkdirgradle01435cdgradle01 437 /Applications/AndroidStudio.app/Contents/gradle/gradle-2.8/bin/gradleinit--typ 查看详情

第25月第2天django项目01

1.exportPATH="$PATH":/Applications/XAMPP/xamppfiles/bin/ sudoln-s/Applications/XAMPP/xamppfiles/lib/libmysqlclient.18.dylib/usr/lib/libmysqlclient.18.dylib  更新20160318的node  3 查看详情

第12月第2天uiscrollview_adjustcontentoffsetifnecessary

1.uiscrollview在调用setFrame,setBounds等方法的时候会默认调用稀有api:_adjustContentOffsetIfNecessary这个方法会改变当前的contentOffset值 如果没有设置 self.automaticallyAdjustsScrollViewInsets=NO;那么(CGPoint)contentOffset=(x=0, 查看详情

第2月第1天gcdasyncsocketdispatch_source_set_event_handler

一、GCDAsyncSocket的核心就是dispatch_source_set_event_handler1.accpet回调accept4Source=dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,socket4FD,0,socketQueue);intsocketFD=socket4FD;dispatch_source_tacceptSou 查看详情

第25月第4天djangochinaorg项目记录01

#------------------------------1.djangochinaorg项目https://github.com/DjangoChinaOrg/Django-China-APIhttps://github.com/DjangoChinaOrg/Django-China-FE 2.vueproxyTableproxyTable:‘/proxy‘:target:‘h 查看详情

第3月第15天afconvertlame

1.//CAF转换成MP3(可以)afconvert-fmp4f-daac-b128000 /Users/amarishuyi/Desktop/sound1.caf/Users/amarishuyi/Desktop/sound1.mp3 http://blog.csdn.net/ysy441088327/article/details/7388351 2.lame#i 查看详情

第27月第10天cmake(代码片段)

1.error:tool‘xcodebuild‘requiresXcode的解决办法 sudoxcode-select--switch/Applications/Xcode.app/Contents/Developer/   https://blog.csdn.net/shorewb/article/details/52447554  2 查看详情

第16月第27天pipinstallvirtualenv

1.pipinstallvirtualenvvirtualenvtestvircdtestvircdScriptsactivatepipinstalldjango==1.9.8 https://zhuanlan.zhihu.com/p/32286726 查看详情

第5月第18天视频编辑水印

1.//***********ForASpecialTimeCABasicAnimation*animation=[CABasicAnimationanimationWithKeyPath:@"opacity"];[animationsetDuration:0];[animationsetFromValue:[NSNumbernumberWithFloat:1.0]];[animationsetT 查看详情

第4月第1天makefile

1.gnumake的函数调用是$,比如 $(substee,EE,feetonthestreet)  PatternRules Makefile里的.c.o等价于 %.o:%.c  .c.o:$(COMPILE)-MT[email protected]-MD-MP-MF$(DEPDIR)/$*.Tpo-c-o[emai 查看详情

第10月第1天storyboarduitableviewcell

1. 如图,我们在Cell的属性界面对其进行了注册,identifier为"TableViewCell"不需要在ViewDidLoad对其进行注册了,如果进行注册的话,则对xcode来说你引用的不是storyboard上的定义的Cel,而是你创建的空Cell类了,所以显示为空白. http://blog.c... 查看详情

第9月第3天uilabelcontentscale

1. http://blog.csdn.net/u012703795/article/details/43706449 查看详情

第11月第14天openglyuv

1.Hereissomesnippetsofcodefrommyproject‘movieplayerforiOS‘.1.fragmentshadervaryinghighpvec2v_texcoord;uniformsampler2Ds_texture_y;uniformsampler2Ds_texture_u;uniformsampler2Ds_texture_v;voidmain(){hig 查看详情

第9月第30天mvp

1. importUIKitstructPerson{//ModelletfirstName:StringletlastName:String}protocolGreetingView:class{funcsetGreeting(greeting:String)}protocolGreetingViewPresenter{init(view:GreetingView,person:Per 查看详情

第10月第28天touchesbegan

1.-(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{[[selfnextResponder]touchesBegan:toucheswithEvent:event];[supertouchesBegan:toucheswithEvent:event];}-(void)touchesMoved:(NSSet*)touchesw 查看详情

第37月第29天avplayer截屏

1.-(void)displayLinkCallback:(CADisplayLink*)sender{CMTimetime=[snapshotOutputitemTimeForHostTime:CACurrentMediaTime()];if([snapshotOutputhasNewPixelBufferForItemTime:time]){lastSnapshotPixelBuffer=[s 查看详情

第16月第3天afurlsessionmanager

1. -(AFURLSessionManagerTaskDelegate*)delegateForTask:(NSURLSessionTask*)task{  NSParameterAssert(task);   AFURLSessionManagerTaskDelegate*delegate=nil;  [self. 查看详情

第21月第6天市场永远是对的

1.cs231nhttps://blog.csdn.net/kangroger/article/list/2http://study.163.com/course/courseMain.htm?courseId=1003223001 2. 我们应该记住,既成的事实一定有它的道理,如果我们不能理解它,恐怕得从自身找原因。如果你交易股票,请记住,如果预测... 查看详情