Re: RunLoop/CFSocket sample code for RAEL apps
Re: RunLoop/CFSocket sample code for RAEL apps
- Subject: Re: RunLoop/CFSocket sample code for RAEL apps
- From: Jeffrey Johnson <email@hidden>
- Date: Fri, 8 Feb 2002 17:36:45 -0500
At 12:19 PM -0800 2/8/02, Douglas Davidson wrote:
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).
<snip>
// 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.
Yes, this is a potentially a Bad Thing on high-numbered ports, where
port stealing can happen [by unprivileged images]. At the time, I was
just trying to get something working, and didn't want to perturb the
incantation, but this should be removed for most apps.
// 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.
While I'm definitely wetter behind the ears on networking than
some/most on this list (I'm a UI weenie), All the code I've seen in
Stevens for a server go through the following:
socket()->bind()->listen()->accept()->read().
My supposition was that CFSocketCreateWithSocketSignature() did the
socket()->bind(), and the first callback was triggered right after
"something internally" returned from listen(). The sparse notes in
CFSocket.h and Stevens don't really map one to one :-).
I burned a day and a half banging my head against the wall, trying to
set up a *single* callback of the various CFSocketCallBackType values
to get a successful read(). Most of my attempts retrieved the native
socket fron the CFSocket and tried a BSD accept()->read(). accept()
sent back a positive low-value fd, but the read always failed (-1),
errno "socket not connected".
It wasn't until my DTS Incident person pointed me to this list (I
thought it was OpenTransport only - guess that's why it was recently
renamed :-)) where the server example had *just* been posted, that
the "aha!" moment happened- (for TCP) the first callback apparently
*must* be a AcceptCallBack, which then should add another socket with
a Data or ReadCallBack (where a BSD read() on the native socket in a
ReadCallBack probably works).
If there's a way to do it for TCP sockets with a single
CFSocket/callback and BSD calls, I couldn't find it. If it's a
requirement to do multiple callbacks for TCP when using the CFSocket
API, now we know (and knowing is half the battle- oh man, GI Joe
flashbacks :-)).
In any case, this socket- creating- another- socket leapfrog was
non-obvious from the headers. Oh nuts, I feel a docs rant coming on.
OWTH, it's Friday. All can tune out now :-).
<RANT>
While I effusely appreciate the engineers on the mailing lists and
and other SmartFriends that answer questions, and want to stress that
I understand that doing so is thankless (Thank You, BTW) and part of
no one's job description, the question remains:
*** What do we (ADC Third Party developer members) have to
do/kill/sacrifice to get Apple (corporate) to fund and publish formal
documentation? ***
BTW, I don't believe it's the onus of the engineers to write
narrative docs: that's why good Tech Writers/Editors are worth their
weight in gold.
We're nearing the *one year anniversary* of the public release of
OSX, and the *CoreFoundation* docs still have holes at basic levels
one can drive a truck through.
"CFData" - supposedly one of the lynchpins of "CollectionServices"?:
last updated 07 Sep *1999*
"Creating and Using CFData Objects :
Beta documentation : This document has not received a full technical
review and therefore might contain inaccuracies."
Which is immediately followed by
"<<forthcoming>>"
wow, that tag might have some inaccuracies, all right :-). And That's
All She Wrote. We're on our own to make sense of the functions by
API/argument names, or what notes that *are* in the headers (some are
better than others).
CFRunLoop? CFSocket? CFMessagePort? narratives completely Missing In
Action. Thank God the list archives are finally searchable (Thanks
Chuq, or whoever was responsible). Don't get me started on trying to
figure out ATSUI to draw anti-aliased text quickly if
DrawThemeTextBox() isn't enough (and why the rendered text won't
match), or the DataBrowser.
And how many Cocoa books are there? Learning Cocoa? Aaron Hillegas' (sp?) book?
And Big Steve had this attitude at WWDC, wondering why we "third
party developers" are "late"? Tell him to hold reeeeaal still, while
I find my ClueBat(tm) ....
</RANT>
--
Thanks
Jeffrey Johnson
Macintosh Development
Wavefunction, Inc.
_______________________________________________
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.