2012-03-28 75 views
2

我試圖添加一些簡單的點對點連接功能到iOS庫。傳出連接的編碼非常簡單,撥打CFStreamCreatePairWithSocketToHost的呼叫連接到遠程主機,並設置用於從其讀取/寫入的流。夠簡單。iOS - 從套接字獲取CFReadStream/CFWriteStream

但是,我找不到一個等價的簡單方法來設置套接字來偵聽/接受傳入連接。於是我又回到基礎知識和使用socket()bind()listen(),並accept()實現低級別的連接處理,圖案主要是這裏的例子後:

http://www.pcs.cnu.edu/~dgame/sockets/server.c

這一切很好,但現在我能夠接受傳入連接我想知道如何去創建CFReadStreamCFWriteStream實例來管理它們。有沒有一種簡單的方法呢?

另外,我知道存在支持異步服務器套接字的CocoaAsyncSocket庫,但我對異步解決方案並不感興趣。

回答

8

好的,原來答案其實很簡單。您可以使用:

void CFStreamCreatePairWithSocket (
    CFAllocatorRef alloc, 
    CFSocketNativeHandle sock, 
    CFReadStreamRef *readStream, 
    CFWriteStreamRef *writeStream 
); 

...到CFReadStreamCFWriteStream綁定到已經連接插座。這個流程對我來說似乎有些落後(即,如果字節已經從套接字等中讀取了,爲什麼不能將某些東西綁定到監聽/服務器套接字,以便每次接受新連接時相應的CFReadStreamCFWriteStream實例會自動設置?),但無論如何。

的代碼是這樣:

int connectedSocketId = accept(socketId, (struct sockaddr *)&clientSocket, &addrlen); 
if (connectedSocketId != -1) { 
    //successful connection 
    CFReadStreamRef clientInput = NULL; 
    CFWriteStreamRef clientOutput = NULL; 
    CFStreamCreatePairWithSocket(kCFAllocatorDefault, connectedSocketId, &clientInput, &clientOutput); 

    if (clientInput && clientOutput) { 
     CFReadStreamSetProperty(clientInput, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); 
     CFWriteStreamSetProperty(clientOutput, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); 
     if (! CFReadStreamOpen(clientInput) || ! CFWriteStreamOpen(clientOutput)) { 
      NSLog(@"Could not initialize streams!"); 
     } 
     else { 
      //use the streams 
     } 
    } 
} 

因此,爲了實現重要的事情:

  1. 這是沒有必要綁定到任何你正在聽的插座;相反,可以將CFReadStreamCFWriteStream實例任意綁定到任何已連接的套接字,即使您已經從/向其讀取/寫入數據。

  2. 對於它所有的花哨的冗長,CFSocketNativeHandle只是一個int。哦,我是如何討厭原始類型的不必要的別名,聽起來像他們不是原始類型。