Re: RunLoop/CFSocket sample code for RAEL apps (LONG, pt1)
Re: RunLoop/CFSocket sample code for RAEL apps (LONG, pt1)
- Subject: Re: RunLoop/CFSocket sample code for RAEL apps (LONG, pt1)
- From: Douglas Davidson <email@hidden>
- Date: Fri, 8 Feb 2002 12:19:07 -0800
On Friday, February 8, 2002, at 10:12 AM, Jeffrey Johnson wrote:
From Douglas Davidson's pthreaded server sample code posted here
(macnetworkprog) on 02/04 (and spending a DTS Incident directing me
here), I've put together some sample code suitable for a Carbon app
using RunApplicationEventLoop(). This code allows a RAEL app to listen
to a TCP port and respond using CFRunLoop callbacks (i.e. no threads
required).
This code could quickly become Bottleneck City, performancewise -
it's really only sufficient for simple, small "request-reply"
transactions. If you're writing a server with lots of connections going
on, you should use threads/the threaded example previously posted as a
base.
But if you have some "backend" Unix program (that shouldn't link to
CarbonLib for one reason or another) that needs to initiate a
connection to a Carbon UI app (a CarbonLib-less pgm can't *initiate* an
AE to a CarbonLib UI app, but can receive and reply to them. Bummer.
Like a phone without a dial/keypad), using this code with a high
numbered TCP socket might work for you. I've also enclosed a short
client program ripped off from Stevens for testing.
In this case you would definitely want to bind to loopback so as not to
expose your socket to the entire world. Even so, your socket is
available to any process on the box, so you are responsible for your own
security. You can also use PF_LOCAL sockets, or pipes, or Mach ports...
// allows any host to connect, might want to change to loopback for
security
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
See above.
// As of this writing, I'm not sure why the socket needs
// REUSEADDR/REUSEPORT set
setsockopt(CFSocketGetNative(*boundSocket),
SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes));
setsockopt(CFSocketGetNative(*boundSocket),
SOL_SOCKET,SO_REUSEPORT,&yes,sizeof(yes));
I would suggest not using these options without understanding what they
mean. Stevens should help here. I included them in my example for
convenience in e.g. running multiple copies of the server or running the
server again right after quitting it.
// Apparently, we need to do a two-step dance to use a CFSocket:
// - Setup the socket first as a "rendevous" socket with a
kCFSocketAcceptCallBack callback
// - When the accept callback fires, create a new CFSocket with the
original "native" (BSD)
// socket with a kCFSocketDataCallBack callback to actually receive
the data.
// - When the data callback fires, the data sent across the socket will
be in dataPtr
// (a CFDataRef).
This is not specific to CFSocket; it's just how TCP sockets work. If
you were using UDP, you would only have one socket. Note that you have
a choice here: you can use kCFSocketDataCallBack, and CFSocket will do
the read for you and hand you the data, or you can use
kCFSocketReadCallBack, and do the read yourself. If you choose the
latter, be sure you actually do read from the socket, or you will keep
getting the callback until you do.
Douglas Davidson
_______________________________________________
macnetworkprog mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/macnetworkprog
Do not post admin requests to the list. They will be ignored.