2012-03-28 32 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。哦,我是如何讨厌原始类型的不必要的别名,听起来像他们不是原始类型。