我从2010年冬天开始在iTunes U上学习斯坦福大学CS193p课程(iOS编程)第17讲的bonjour / NSStream示例代码。示例代码可用here。
在一个坚果shell中,示例代码创建一个套接字并绑定到端口0,以便为它提供一个空闲端口。然后,它使用NSNetService
(bonjour)发布该端口的服务。应用启动时也会启动NSNetServiceBrowser
。可用服务位于UITableView
。选择单元格后,将解析相应的服务,创建NSOutputStream
,并可以发送数据。
这是一个天真的实现,因为如果连接已经存在,则会拒绝连接。我的问题是,处理多个连接的正确方法是什么?一旦多个客户端连接到服务器,服务器如何区分它们?即如何将数据专门发送给一个客户而不是其他客户?
- (void) _acceptConnection:(int)fd
{
int junk;
// If we already have a connection, reject this new one. This is one of the
// big simplifying assumptions in this code. A real server should handle
// multiple simultaneous connections.
if ( self.isReceiving ) {
junk = close(fd);
assert(junk == 0);
} else {
[self _startReceive:fd];
}
}
// Called by CFSocket when someone connects to our listening socket.
// This implementation just bounces the request up to Objective-C.
static void AcceptCallback(CFSocketRef s,
CFSocketCallBackType type,
CFDataRef address,
const void *data,
void *info)
{
ReceiveServer * obj;
assert(type == kCFSocketAcceptCallBack);
assert(data != NULL);
obj = (ReceiveServer *) info;
assert(obj != nil);
assert(s == obj->_listeningSocket);
[obj _acceptConnection:*(int *)data];
}
答案 0 :(得分:1)
我并不是特别熟悉该课程或示例代码,但是:将用于处理连接的代码从接受新连接的代码中分离出来。因此,在发布的代码中,您将-startReceive:
方法及其调用的所有内容移动到另一个类。
然后,每次接受连接时,创建该另一个类的实例。该实例将负责处理该连接上的所有通信。初始化期间将给出有关连接(主要是fd)的信息。服务器的主控制器对象可以将这些实例保存在数组中。
从这里开始的事情将取决于您的服务器实际执行的操作。至少,您的连接对象需要在关闭时通知主控制器对象,因此主控制器可以从阵列中删除它们。您可以使用通知或委托模式。