Problem closing CFWriteStream [moved from darwin-dev, as it seems more appropriate here]
Problem closing CFWriteStream [moved from darwin-dev, as it seems more appropriate here]
- Subject: Problem closing CFWriteStream [moved from darwin-dev, as it seems more appropriate here]
- From: Eli Bach <email@hidden>
- Date: Fri, 20 Jun 2008 02:23:58 -0700
How can I do an orderly vs a disorderly TCP disconnect using
CFWriteStream in my daemon?
For the daemon [the server], I use:
[to listen to the server socket on the runloop]
CFSocketCreate(PF_INET, SOCK_STREAM, IPPROTO_TCP,
kCFSocketAcceptCallBack),
setsockopt(CFSocketGetNative(), SO_REUSEADDR)
CFSocketSetAddress(0.0.0.0:port)
CFSocketCreateRunLoopSource()
CFRunLoopAddSource
Then in the callback that a connection was made, to create and setup
the read/write streams:
CFStreamCreatePairWithSocket()
CFReadStreamSetProperty(kCFStreamPropertyShouldCloseNativeSocket, true)
CFWriteStreamSetProperty(kCFStreamPropertyShouldCloseNativeSocket, true)
CFReadStreamSetClient(kCFStreamEventOpenCompleted bitor
kCFStreamEventHasBytesAvailable
bitor kCFStreamEventCanAcceptBytes bitor kCFStreamEventErrorOccurred
bitor kCFStreamEventEndEncountered)
CFWriteStreamSetClient(kCFStreamEventOpenCompleted bitor
kCFStreamEventHasBytesAvailable
bitor kCFStreamEventCanAcceptBytes bitor kCFStreamEventErrorOccurred
bitor kCFStreamEventEndEncountered)
CFReadStreamScheduleWithRunLoop()
CFWriteStreamScheduleWithRunLoop()
CFReadStreamOpen()
CFWriteStreamOpen()
then I only handle events for these streams from callbacks on the
runloop.
For the client, I use
CFStreamCreatePairWithSocketToHost()
CFReadStreamSetProperty(kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue
CFWriteStreamSetProperty(kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue
and the code picks up in the above outline at the same spot [and the
code is shared between client and server].
Just calling CFWriteStreamClose() doesn't inform the other side of the
connection that it's "closed" [ie, a half-open connection].
The second thing is whether calling CFWriteStreamClose() forces the
write buffer to be flushed [at least, so any data buffered within CF
is pushed to the kernel]. Even if I get the native socket, then call
shutdown() on it, how can I be sure that the CFWriteStream isn't still
holding some buffered data?
Basically, I'm trying to something that I think would be fairly
common, which is doing an orderly disconnect, where a client sends a
'logout' message and closes the write stream, the server receives the
'logout' [and then the read stream says it's not connected anymore],
then the server replies with a 'logged out' message and closes it's
write stream, which the client receives and then the client's read
stream says it's not connected anymore.
From my testing, it seems that you can't do this with CFStreams
directly, even though the API presents as having separate read/write
streams, it only does a 'close' once both read&write streams are closed.
Third, if an error happens, and I want to tear down the connection in
a 'disorderly' fashion [ie, not waiting for the send buffer to be
flushed to the client, which could potentially take minutes for TCP to
timeout], how do I do this?
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden