我正在尝试为iOS库添加一些简单的点对点连接功能。传出连接的编码很简单;对CFStreamCreatePairWithSocketToHost
的调用连接到远程主机并设置用于从/向其读/写的流。很简单。
但是,我找不到一种设置套接字来监听/接受传入连接的等效简单方法。所以我回到基础并使用socket()
,bind()
,listen()
和accept()
来实现低级连接处理,主要是在这里的示例之后进行图案化:
http://www.pcs.cnu.edu/~dgame/sockets/server.c
这一切都很好,但现在我能够接受传入的连接,我想知道如何创建CFReadStream
和CFWriteStream
实例来管理它们。有这么简单的方法吗?
顺便说一句,我知道存在一个支持异步服务器套接字的CocoaAsyncSocket
库,但我真的对异步解决方案不感兴趣。
答案 0 :(得分:8)
好的,事实证明答案实际上相当简单。您可以使用:
void CFStreamCreatePairWithSocket (
CFAllocatorRef alloc,
CFSocketNativeHandle sock,
CFReadStreamRef *readStream,
CFWriteStreamRef *writeStream
);
...将CFReadStream
和CFWriteStream
绑定到已连接的套接字。这个流程对我来说似乎有点倒退(即如果已经从套接字中读取了字节等等,为什么不能将某些内容绑定到侦听/服务器套接字,以便每次接受新连接时相应的CFReadStream
和CFWriteStream
实例会自动设置?),但无论如何。
代码如下:
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
}
}
}
所以要实现的重要事项是:
没有必要将任何内容绑定到您正在侦听的套接字上;相反,即使您已经从/向它读取/写入数据,也可以将CFReadStream
和CFWriteStream
实例任意绑定到任何已连接的套接字。
CFSocketNativeHandle
只是int
。哦,我如何厌恶原始类型的不必要的混淆,听起来它们不是原始类型。