Re: Closing CFWriteStreams (re-sent)
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=BmkjsJW+dL6FTrMNME9HfzIdiUgN648PmtqaOi+OwQE=; b=cwkz5/vm5ZjsAhv2IL+jLe9fTxEZEYB+9j4Y4jiTj60eOseFEnapeUygAkQMOlIIur Kjirc6/CoNmrySk4jEL9GGBI1iQnnecQnW278LRo7qM3U4EupL1dBUcmypRudASSj3Gd RwmjNwENyG6GP22TVeJ0g8vZTBDoD/rjGLt3g= Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=bXgjNIJqaNw2GL7NNpB1ABgptezrHbK/WSBKDMgHSa44WWWcTJ3XDV63cGRFKpznrI xJTTE3F1MV3vGpaNhputbTYkjculiUwehLsxLU/KBOg3UtF7MvKGOAIa2mxpDe1ZmpiS GE/UjV1IUxIaGffFDjYvgtnL0Rp9CqRTYbQ6I= On Jun 19, 2008, at 7:02 PM, Terry Lambert wrote: and then call shutdown(2) on the fd you get back. See also: Terry, For the client, I use Or is there another, better way to do this? _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... On Jun 19, 2008, at 6:35 PM, Eli Bach wrote: How can I do an orderly vs a disorder TCP disconnect using CFWriteStream in my daemon? If I CFWriteStreamClose() immediately after my last CFWriteStreamWrite(), the data may or may not get sent out.
From the documentation, I gather that CFWriteStream buffers data internally before actually sending it down the wire, and I can query it if I can add data to the buffer, but there doesn't seem to be a way to query if that write buffer is empty, or to flush the buffer before closing the stream. I'm using CFRead/WriteStreams using events on a single runloop.
You do not give enough information about how you got it associated with the stream in the first place, but typically, you can do a: CFWriteStreamCopyProperty( stream, kCFStreamPropertySocketNativeHandle) It may also do this automatically in the close, if you set the socket back to blocking, if you are using it non-blocking. Typically, a close flushes buffered output before returning. <http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/CFN...
which shows up in the first page of google results for "CFWriteStreamClose socket". -- Terry First, I resent the message because I didn't receive the first one from the list [and from way back, I expected to receive it]. Yes, I have poked around in that document [as it also shows up in the documentation in XCode] searching for info related to CFWriteStream. 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. 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]. Right now, it seems that using CFWriteStreamClose(), then releasing the stream with the above setup doesn't force the data stream to be flushed. I'll try switching 'kCFStreamPropertyShouldCloseNativeSocket' to false, then get the socket and do a close() or shutdown() on the socket explicitly. Of course, I hate the idea of needing to spin off another thread just to call close() [as it should block waiting for all the data to be sent, and would halt the runloop doing it there]. I'll also look around in the CF source that is available, to see how it might be implemented [as there's no guarantee that Apple actually uses that exact code on MacOSX]. This email sent to site_archiver@lists.apple.com
participants (1)
-
Eli Bach