你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS從零開始學習socket編程——高並發多線程服務器

iOS從零開始學習socket編程——高並發多線程服務器

編輯:IOS開發綜合

在上一篇文章《iOS從零開始學習socket編程——HTTP1.0服務器端》中我們已經簡單的接觸了OC搭建的HTTP服務器。

出於用戶體驗和魯棒性考慮,這裡把這個HTTP服務器改進成多線程的。
首先,AnsycSocket這個類是基於OC的Runloop實現的,Runloop實現了方法的異步調用但並不支持多線程。
在這裡首先簡單區分一下多線程和方法異步調用的區別。他們都可以避免線程的阻塞,只不過多線程是新開一個線程處理任務,處理完成之後通知主線程;而方法異步調用本質上還是在主線程裡調用方法,只不過主線程並不會阻塞著等待方法的執行結果,而是繼續執行原有的任務,直到方法執行完成之後才進行相應的處理。從某種意義上來說,socket編程並不總需要服務器支持多線程,因為新增一個線程本身也會增加CPU的負擔,而他們的執行效果也基本類似。
然而,考慮一下這種情況,我們就應該發現多線程也有他必不可少的理由:假設用戶上傳一張圖片並且請求對這個圖片進行處理,假設圖片的處理非常復雜並且涉及到大量計算,此時如果任然在主線程中執行處理圖片的方法,系統的執行效率會大幅度下降,用戶體驗變差。如果新增一個線程,那麼多核處理器的處理優勢將會被充分發揮,大大提高用戶體驗。
因此總結起來就是:我們並不需要為每一個新的socket連接新增一個線程,確應該在處理數據的時候,充分發揮多核處理器的優勢,新增線程,提高執行速度。
也正因為如此,AnsycSocket本身的回調函數是異步調用,並不支持多線程,如果在子線程中調用AnsycSocket類對象的writeData方法(向socket中寫入數據)將不會起任何作用。解決方法是,將數據的處理放在新的線程,並在主線程中執行writeData方法和UI相關的改變。
重點需要修改的函數是didReadData方法:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    //處理數據
}

我們只用將這個方法進行簡單地修改就可以支持多線程處理數據。

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    __block AsyncSocket *localSocket = sock;
    __block NSData *localData = data;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@thread = %@,[NSThread currentThread]);
        [self dealWithData:localSocket Data:localData];
    });
}

這裡創建了三個block類型的對象避免在block中出現循環引用的問題。
接下來實現dealWithData方法:

- (void)dealWithData:(AsyncSocket *)sock Data:(NSData *)data{
    //這個方法和AnsycSocket的didReadData方法極為類似
    /*
        處理相關數據
    */
    dispatch_async(dispatch_get_main_queue(), ^{
        [sock writeData:data withTimeout:-1 tag:ECHO_MSG];
        [sock disconnectAfterWriting];
    });
}

可以看出,只是簡單的新增了一個線程並且把原來需要在didReadData方法中實現的內容搬到了自定義的函數中。處理完成數據後,記得在主線程中寫入數據即可。

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved