I have been studying the bonjour/NSStream sample code from lecture #17 of Stanford's CS193p course (iOS programming) on iTunes U from the winter of 2010. The example code is available here.
In a nut shell, the sample code creates a socket and binds to port 0 so that it will be given a free port. It then publishes a service with that port using NSNetService
(bonjour). An NSNetServiceBrowser
is also started when the app starts up. Available services are placed in a UITableView
. When a cell is selected, the corresponding service is resolved, an NSOutputStream
is created, and data can be sent.
This is a naive implementation because connections are rejected if a connection already exists. My question is, what is the proper way to handle multiple connections? Once multiple clients are connected to the server, how does the server distinguish between them? i.e. How can data be sent specifically to one client and not the others?
- (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];
}