Re: Why can an NSConnection only vend objects if sendPort == receivePort?
Re: Why can an NSConnection only vend objects if sendPort == receivePort?
- Subject: Re: Why can an NSConnection only vend objects if sendPort == receivePort?
- From: Wade Tregaskis <email@hidden>
- Date: Mon, 1 Sep 2003 22:56:48 +1000
This is a followup to my previous email to add new information. I'm
still yet to find a solution; indeed, as I'm about to show, I now have
even less of an idea what the problem is.
This message is very long, because it includes some detailed debugging
info. Sorry about the verbosity.
As I wrote previously:
Is it a design issue, or simply an arbitrary limit? I had hoped it
were simply a case of over-zealous documentation, but it does indeed
seem that NSConnections [where receive == send] cannot accept vended
objects from the other end. The client port sends some data (78
bytes) to the server port, which then replies with a small amount of
data (10 bytes). NSConnection's rootProxy method then returns nil to
the client code. Further calls to rootProxy send the same data (with
only the message count incremented), and receives the same reply
(again, with only the message count incremented). I can't tell
whether the server is returning some kind of error or the proxied
object, but either way, the client isn't accepting it.
To append to this, I've found that even if I use NSConnection's in the
proper way (server receive == send port, client has receive = nil, send
== valid port) the behaviour is identical, only with an extra port in
there making my debugging output more convoluted (on the up side, this
did reveal a run loop issue I hadn't previously been able to reliably
reproduce).
Anyway, the following is the debug output, with some comments added
where explanation is necessary.
// connection is established, SSL stuff over and done with, all good
to go
// Note that the 'bb1f0' at the start of each line simply denotes the
run loop in which this is taking place; good for distinguishing
between client(s) & server(s)
bb1f0 SecureSocketPort(a8a8c0) - sendBeforeDate:17h20m34s msgid:0
components:12ea690 from:aa18e0 reserved:0 // This is called by
NSConnection, presumably
bb1f0 SecureSocketPort(a8a8c0) - isValid
bb1f0 SecureSocketPort(a8a8c0) - socketAvailable
bb1f0 {YES}
bb1f0 {YES}
bb1f0 SecureSocketPort(a8a8c0) - isConnected
bb1f0 {YES}
bb1f0 Connected and valid; sending message...
bb1f0 SecureSocketPort(aa18e0) - encodedForm
bb1f0 SecureSocketPort(aa18e0) - encodedString
bb1f0 {"131.172.83.106:49413"} // The 'from' port's local address
bb1f0 {<3133312e 3137322e 38332e31 30363a34 39343133 >} // The raw
data form of the above string; that's all encodedForm does
bb1f0 Number of objects = 1 // [components count]
bb1f0 NSData - <04edfe1f 0e010b01 01010d4e 53496e76 6f636174
696f6e00 00010101 104e5344 69737461 6e744f62 6a656374 00000001
01010102 01010b72 6f6f744f 626a6563 74000101 0440403a 00014001 0000>
// First component
bb1f0 No payload compression
bb1f0 Sending message // Writing to socket using SSLWrite
--- BlockCryptor::outputSize inSize 0x90 outSize 0x90 final 0
inBufSize 0x0
--- BlockCryptor::inputSize inSize 0x90 outSize 0x90 mInBufSize 0x0
=== BlockCryptor::update encrypt 1 inSize 0x90 outSize 0x90
bb1f0 SecureSocketPort - sslWriteFunction(b59270) // My write
method, called by SecureTransport
bb1f0 SecureSocketPort(a8a8c0) - netsocketDataSent:b59270
bb1f0 Wrote 149 bytes // This line and the above confirm the data
is being sent. Just in case anyone thought of asking. :)
bb1f0 {"No error"}
===SSLWrite: req 118 moved 118 status 0?
// etc
The result is the following:
// again, socket is already connected, SSL established, etc etc.
b446f0 SecureSocketPort(b56bc0) - netsocket:240d60 dataAvailable:149
// Got the same amount of data, as you'd expect
b446f0 SecureSocketPort(b56bc0) - isConnected
b446f0 {YES}
b446f0 SecureSocketPort - sslReadFunction(240d60)
b446f0 Read 5 bytes // My protocol has a 5-byte packet header
b446f0 {"No error"}
b446f0 SecureSocketPort - sslReadFunction(240d60)
b446f0 Read 144 bytes // Read the remaining data (payload)
b446f0 {"No error"}
--- BlockCryptor::outputSize inSize 0x90 outSize 0x90 final 0
inBufSize 0x0
--- BlockCryptor::inputSize inSize 0x90 outSize 0x90 mInBufSize 0x0
=== BlockCryptor::update encrypt 0 inSize 0x90 outSize 0x90
===SSLRead : req 5 moved 5 status 0?
===SSLRead : req 113 moved 113 status 0?
b446f0 Leaving payload uncompressed
b446f0 SecureSocketPort(b56bc0) - decodePacket:12e9160 // Decodes
the actual payload; the message
b446f0 SecureSocketPort(b56bc0) - delegate
b446f0 {b45ba0}
b446f0 Message id = 0 // As was sent
b446f0 SecureSocketPort -
secureSocketPortForAddress:"131.172.83.106:49413" // This address
comes from the payload, and as you can see is the one we sent
b446f0 SecureSocketPort -
secureSocketPortForHost:"131.172.83.106" port:49413
b446f0 Found existing instance 1281c40 // In this case I've
taken a sample after several hundred message-reply cycles, so the
return port already exists
b446f0 {1281c40}
b446f0 {1281c40}
b446f0 SecureSocketPort(1281c40) - isReady
b446f0 {YES}
b446f0 Number of objects = 1 // As expected
b446f0 NSData - <04edfe1f 0e010b01 01010d4e 53496e76 6f636174
696f6e00 00010101 104e5344 69737461 6e744f62 6a656374 00000001
01010102 01010b72 6f6f744f 626a6563 74000101 0440403a 00014001 0000>
// This seems exactly the same as the data that was sent
b446f0 SecureSocketPort(b56bc0) - retain
b446f0 SecureSocketPort(1281c40) - retain
b446f0 Dispatching message to delegate // [[self delegate]
handlePortMessage:....]
// Note that the delegate is taken as the connection passed in the
addConnection:toRunLoop:forMode: method... this seems to work; I
managed to break inside the code that was handling the message, and it
shows NSConnection seems to be trying to deal with the message
appropriately.
// etc
The delegate (the NSConnection in this case) then immediately sends a
"reply" (without returning from handlePortMessage:), which looks a lot
like what I've shown already, except that the single components NSData
object is now:
b446f0 NSData - <04cefe2f 0e010b00 0000>
Again, this gets back to the client just fine:
bb1f0 NSData - <04cefe2f 0e010b00 0000>
And so on, ad infinum. I really wish I knew what this result is.. it
seems awfully short to contain any meaningful data, but I don't
otherwise know how to interpret it.
To be complete, I should assure you there is nothing wrong with how I'm
trying to use DO - I've simply modified the SimpleThreads example from
Apple, adding in the extra configuration stuff required on the ports,
and little else. The server is setting a valid root object, and the
NSConnection is accepting it. Yet the client NSConnection is
definitely returning nil for rootProxy. As I mentioned, each call to
rootProxy triggers the cycle detailed above, returning nil right after
the short response is received, above.
I just cannot fathom what is not being done properly in my NSPort
subclass.
FWIW, I'll be posting the source to this class very soon on
Sourceforge, along with the modified SimpleThreads demo, if anyone
wants a look themselves.
Wade Tregaskis
-- Sed quis custodiet ipsos custodes?
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.