0

从 2010 年冬天开始,我一直在研究 iTunes U 上斯坦福 CS193p 课程(iOS 编程)第 17 讲课中的 bonjour/NSStream 示例代码。示例代码可在此处获得。

简而言之,示例代码创建一个套接字并绑定到端口 0,以便为它提供一个空闲端口。NSNetService然后它使用(bonjour)发布具有该端口的服务。应用NSNetServiceBrowser程序启动时也会启动。可用的服务放在一个UITableView. 当一个cell被选中时,对应的service就被解析,一个anNSOutputStream被创建,就可以发送数据了。

这是一个幼稚的实现,因为如果连接已经存在,连接将被拒绝。我的问题是,处理多个连接的正确方法是什么?一旦多个客户端连接到服务器,服务器如何区分它们?即如何将数据专门发送给一个客户而不是其他客户?

- (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];
}
4

1 回答 1

1

我并不特别熟悉该课程或示例代码,但是:将用于处理连接的代码与接受新连接的代码分开到不同的类中。因此,在发布的代码中,您-startReceive:会将方法及其调用的所有内容移至另一个类。

然后,每次接受连接时,创建另一个类的实例。该实例将负责处理该连接上的所有通信。它会在初始化期间获得有关连接(主要是 fd)的信息。服务器的主控制器对象可以将这些实例保存在一个数组中。

事情从何而来将取决于您的服务器实际执行的操作。至少,您的连接对象需要在它们关闭时通知主控制器对象,以便主控制器可以将它们从数组中删除。您可以为此使用通知或委托模式。

于 2012-05-10T23:51:02.427 回答