首先介紹幾個知識點
1 NSNetService?
NSNetService可以是服務提供者生成的一個服務,然后加到runloop中,并運行服務。這樣后者就可以獲取到該服務的動態,包括發現該服務,該服務移除等。發現服務獲取到的NSNetService也是不完整的,不包括txt data,address和port的,但是包括了其他信息,例如name,type,domain。
2 NSStream
NSStream 分為NSInputStream(read)和NSOutputStream(write)??
1.從數據源創建和初始化一個NSInputStream實例
2.將輸入流對象配置到一個run loop,open the stream
[readStream setDelegate:self];
[readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[readStream open];
3. 通過流對象的delegate函數處理事件
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
typedefNS_OPTIONS(NSUInteger, NSStreamEvent) {
NSStreamEventNone =0,
NSStreamEventOpenCompleted =1UL <<0,
NSStreamEventHasBytesAvailable =1UL <<1,
NSStreamEventHasSpaceAvailable =1UL <<2,
NSStreamEventErrorOccurred =1UL <<3,
NSStreamEventEndEncountered =1UL <<4
};
4. 當所有數據讀完,進行流對象的內存處理
[stream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[stream close];
NSInputStream類有如下接口:
- (NSInteger)read:(uint8_t*)buffer maxLength:(NSUInteger)len;
從流中讀取數據到 buffer 中,buffer 的長度不應少于 len,該接口返回實際讀取的數據長度(該長度最大為 len)。
- (BOOL)getBuffer:(uint8_t**)buffer length:(NSUInteger*)len;
獲取當前流中的數據以及大小,注意 buffer 只在下一個流操作之前有效。
- (BOOL)hasBytesAvailable;
檢查流中是否還有數據。
NSOutputStream類有如下接口:
- (NSInteger)write:(constuint8_t*)buffer maxLength:(NSUInteger)len;
將 buffer 中的數據寫入流中,返回實際寫入的字節數。
- (BOOL)hasSpaceAvailable;
檢查流中是否還有可供寫入的空間。
3 CFSocketRef?
CFSocketRef 一個C的api
根據連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:服務器監聽,客戶端請求,連接確認。
(1)服務器監聽:是服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態,實時監控網絡狀態。
(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。
(3)連接確認:是指當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連接就建立好了。而服務器端套接字繼續處于監聽狀態,繼續接收其他客戶端套接字的連接請求。
先說服務端
Server?
第一步? 創建系統級的socket,并綁定端口
port=0是讓系統自動隨機找一個空閑端口 先綁定socket bind() -> listen()
第二步 這里包裝socket的目的是便于后面的事件偵聽和處理,把基于原生態socket的開發轉到iOS的層面上來,這里accept事件偵聽函數是AcceptCallback,并在單獨thread中執行。
第三步:通過NSNetService發布socket
這里是基于NSNetService把先前創建的socket發布出去,便于clienti連接和請求
client發起socket連接請求
這里是client通過前面server發布出來了netservice,發起對socket的連接
server監聽并處理數據請求,server會在accept的事件偵聽的回調函數里對socket打開stream
把網絡的networkStream 寫到 fileStream。
客戶端?
這里的過程與server端正好相反,是從file的Inputstream中讀入數據,并寫入網絡的outputsteam中。
demo ?官網地址