如何使用CFSocket修复天真的服务器实现以允许多个连接

时间:2012-05-10 21:57:43

标签: objective-c network-programming client-server nsstream cfsocket

我从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];
}

1 个答案:

答案 0 :(得分:1)

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

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

从这里开始的事情将取决于您的服务器实际执行的操作。至少,您的连接对象需要在关闭时通知主控制器对象,因此主控制器可以从阵列中删除它们。您可以使用通知或委托模式。