iOS - 从套接字获取CFReadStream/CFWriteStream

aro*_*oth 2 sockets networking ios

我正在尝试为iOS库添加一些简单的点对点连接功能.传出连接的编码很简单; 调用CFStreamCreatePairWithSocketToHost连接到远程主机并设置用于从/向其读/写的流.很简单.

但是,我找不到一个等效的简单方法来设置套接字来监听/接受传入的连接.于是我又回到基础知识和使用socket(),bind(),listen(),并accept()实现低级别的连接处理,这里的例子后,大部分图案:

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

这一切都很好,但现在我能够接受传入的连接,我想知道如何创建CFReadStreamCFWriteStream实例来管理它们.有这么简单的方法吗?

顺便说一句,我知道CocoaAsyncSocket存在一个支持异步服务器套接字的库,但我真的对异步解决方案不感兴趣.

aro*_*oth 8

好的,事实证明答案实际上相当简单.您可以使用:

void CFStreamCreatePairWithSocket (
    CFAllocatorRef alloc,
    CFSocketNativeHandle sock,
    CFReadStreamRef *readStream,
    CFWriteStreamRef *writeStream
);
Run Code Online (Sandbox Code Playgroud)

...绑定一个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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,要实现的重要事项是:

  1. 没有必要将任何内容绑定到您正在侦听的套接字上; 相反,它可以任意绑定CFReadStreamCFWriteStream实例到任何已经连接的套接字,即使你已经从/向它读取/写入数据.

  2. 尽管它看起来CFSocketNativeHandle很花哨,但它只是一个int.哦,我如何厌恶原始类型的不必要的别名,听起来它们不是原始类型.