Big picture relationships between NSConnection, NSInputStream, NSOutputStream etc

  • Hi

    I'm working my way through the "Distributed Objects" documentation and
    am confused about when to use NSConnection, NSInputStream,
    NSOutputStream etc. The PictureBrowser example project doesn't even
    seem to use NSConnection and does its thing just fine. Reading the
    NSConnection docs, I notice the conspicuous absence of any method that
    actually allows the transfer of messages and data. It just seems like
    something that allows you to connect to something ... and then has not
    a single method to actually do anything with that connection.

    I looked at several of the example projects but they're all over the
    map. Some use CF functions, some use raw BSD sockets, PictureBrowser
    uses NSNetService (something not even mentioned in the Distributed
    Object docs) So what is the overview of the function and
    interrelationships between these different parts and importantly, what
    exactly does one do with an NSConnection?

    Thanks for any help
  • Hi Ken-

    I have spent a lot of time in those docs :-)  In a nutshell, here's
    how I see NSConnection and DO... properly set up, NSConnections on the
    server and client side can enable you to pretty much ignore the fact
    that two objects live in separate processes.  You'll just use regular
    obj-c messaging between them.  On the server side, you get a
    connection, assign it a root object, and "advertise" its presence:

    NSConnection *theConnection = [NSConnection defaultConnection];
    [theConnection setRootObject:myServerController];
    if(![theConnection registerName:@"myServerName"]){
    // undesirable, but unlikely
    }

    On the client side, you need to grab the server-side object (the
    "vended" object in the docs) like so...

    id myServerObject = [[NSConnection
    rootProxyForConnectionWithRegisteredName:@"myServerName host:nil]
    retain];

    You might typically specify a communications protocol to use (an obj-c
    protocol that you create defining the messages that the server object
    understands), and also message the server with a reference to self
    (the client object) so the server can hang on to a reference to it...

    [(NSDistantObject *)myServerObject
    setProtocolForProxy:@protocol(myServerProtocol)];
    [myServerObject setClientObject:self];

    (Note that "setClientObject" is something you implement yourself, can
    be named as desired, and its function is to retain a reference to the
    client object).  Now the server can send regular objective-c messages
    to the client object, and the client can send regular objective-c
    messages to the server object.  Both objects are represented by a
    stand-in instance of NSDistantObject in each other's address spaces.

    Using NSConnection as above, you really don't need any of the other
    classes you mentioned.

    Some caveats: Distributed Objects is not present in the iPhone OS, and
    I have encountered troubles (that did not have workarounds last I
    heard) when using DO with garbage collection.

    Also to clarify, NSNetService is not directly related to DO, but might
    be more familiar to you as Bonjour - it is used to discover other
    processes that advertise their presence on the network.

    Hope this helps!

    John

    Positive Spin Media
    http://www.positivespinmedia.com

    On Dec 3, 2008, at 8:22 PM, Ken Tozier wrote:

    > Hi
    >
    > I'm working my way through the "Distributed Objects" documentation
    > and am confused about when to use NSConnection, NSInputStream,
    > NSOutputStream etc. The PictureBrowser example project doesn't even
    > seem to use NSConnection and does its thing just fine. Reading the
    > NSConnection docs, I notice the conspicuous absence of any method
    > that actually allows the transfer of messages and data. It just
    > seems like something that allows you to connect to something ... and
    > then has not a single method to actually do anything with that
    > connection.
    >
    > I looked at several of the example projects but they're all over the
    > map. Some use CF functions, some use raw BSD sockets, PictureBrowser
    > uses NSNetService (something not even mentioned in the Distributed
    > Object docs) So what is the overview of the function and
    > interrelationships between these different parts and importantly,
    > what exactly does one do with an NSConnection?
    >
  • Thanks John. That cleared up a few things.

    Ultimately, what I want to do, is talk directly to a MySQL database
    without the need for the MySQL libraries. The libraries target
    specific processors and OS versions which makes maintenance a royal
    pain. I was thinking I could bypass the whole library zoo by doing
    something ike the following

    #define DEFAULT_MYSQL_PORT_NUMBER    3306
    #define DEFAULT_HOST_NAME    @"locahost"

    NSSocketPort    *socket            = [[NSSocketPort alloc] initRemoteWithTCPPort:
    DEFAULT_MYSQL_PORT_NUMBER host: DEFAULT_HOST_NAME];
    NSConnection    *connection        = [[NSConnection alloc] initWithReceivePort:
    nil sendPort: socket];

    In tests, this seemed to connect OK, but I take it from your
    explanation, that I would need to send objective C messages which MySQ
    doesn't grok. In this case, would I need to set up one or both of
    NSInputStream, NSOutputStream to send and receive data? Or would I
    have to go even lower into BSD socked land (a la PictureBrowser) to do
    this sort of thing?


    On Dec 3, 2008, at 10:54 PM, John Pannell wrote:

    > Hi Ken-
    >
    > I have spent a lot of time in those docs :-)  In a nutshell, here's
    > how I see NSConnection and DO... properly set up, NSConnections on
    > the server and client side can enable you to pretty much ignore the
    > fact that two objects live in separate processes.  You'll just use
    > regular obj-c messaging between them.  On the server side, you get a
    > connection, assign it a root object, and "advertise" its presence:
    >
    > NSConnection *theConnection = [NSConnection defaultConnection];
    > [theConnection setRootObject:myServerController];
    > if(![theConnection registerName:@"myServerName"]){
    > // undesirable, but unlikely
    > }
    >
    > On the client side, you need to grab the server-side object (the
    > "vended" object in the docs) like so...
    >
    > id myServerObject = [[NSConnection
    > rootProxyForConnectionWithRegisteredName:@"myServerName host:nil]
    > retain];
    >
    > You might typically specify a communications protocol to use (an obj-
    > c protocol that you create defining the messages that the server
    > object understands), and also message the server with a reference to
    > self (the client object) so the server can hang on to a reference to
    > it...
    >
    > [(NSDistantObject *)myServerObject
    > setProtocolForProxy:@protocol(myServerProtocol)];
    > [myServerObject setClientObject:self];
    >
    > (Note that "setClientObject" is something you implement yourself,
    > can be named as desired, and its function is to retain a reference
    > to the client object).  Now the server can send regular objective-c
    > messages to the client object, and the client can send regular
    > objective-c messages to the server object.  Both objects are
    > represented by a stand-in instance of NSDistantObject in each
    > other's address spaces.
    >
    > Using NSConnection as above, you really don't need any of the other
    > classes you mentioned.
    >
    > Some caveats: Distributed Objects is not present in the iPhone OS,
    > and I have encountered troubles (that did not have workarounds last
    > I heard) when using DO with garbage collection.
    >
    > Also to clarify, NSNetService is not directly related to DO, but
    > might be more familiar to you as Bonjour - it is used to discover
    > other processes that advertise their presence on the network.
    >
    > Hope this helps!
    >
    > John
    >
    > Positive Spin Media
    > http://www.positivespinmedia.com
    >
    > On Dec 3, 2008, at 8:22 PM, Ken Tozier wrote:
    >
    >> Hi
    >>
    >> I'm working my way through the "Distributed Objects" documentation
    >> and am confused about when to use NSConnection, NSInputStream,
    >> NSOutputStream etc. The PictureBrowser example project doesn't even
    >> seem to use NSConnection and does its thing just fine. Reading the
    >> NSConnection docs, I notice the conspicuous absence of any method
    >> that actually allows the transfer of messages and data. It just
    >> seems like something that allows you to connect to something ...
    >> and then has not a single method to actually do anything with that
    >> connection.
    >>
    >> I looked at several of the example projects but they're all over
    >> the map. Some use CF functions, some use raw BSD sockets,
    >> PictureBrowser uses NSNetService (something not even mentioned in
    >> the Distributed Object docs) So what is the overview of the
    >> function and interrelationships between these different parts and
    >> importantly, what exactly does one do with an NSConnection?
    >>
    >
  • Hi Ken-

    You've got it: the intent with NSConnection is to vend proxy objects
    and get proxy objects for the DO system, facilitating communication
    via obj-c messaging.

    I can't speak from much experience on your other options.  Apple seems
    to provide a number of levels of networking abstraction - I can't
    speak to which would be best for your task... hopefully some others
    have better expertise!

    John

    On Dec 3, 2008, at 9:14 PM, Ken Tozier wrote:

    > Thanks John. That cleared up a few things.
    >
    > Ultimately, what I want to do, is talk directly to a MySQL database
    > without the need for the MySQL libraries. The libraries target
    > specific processors and OS versions which makes maintenance a royal
    > pain. I was thinking I could bypass the whole library zoo by doing
    > something ike the following
    >
    > #define DEFAULT_MYSQL_PORT_NUMBER    3306
    > #define DEFAULT_HOST_NAME    @"locahost"
    >
    > NSSocketPort    *socket            = [[NSSocketPort alloc]
    > initRemoteWithTCPPort: DEFAULT_MYSQL_PORT_NUMBER host:
    > DEFAULT_HOST_NAME];
    > NSConnection    *connection        = [[NSConnection alloc]
    > initWithReceivePort: nil sendPort: socket];
    >
    > In tests, this seemed to connect OK, but I take it from your
    > explanation, that I would need to send objective C messages which
    > MySQ doesn't grok. In this case, would I need to set up one or both
    > of NSInputStream, NSOutputStream to send and receive data? Or would
    > I have to go even lower into BSD socked land (a la PictureBrowser)
    > to do this sort of thing?
    >
    >
    > On Dec 3, 2008, at 10:54 PM, John Pannell wrote:
    >
    >> Hi Ken-
    >>
    >> I have spent a lot of time in those docs :-)  In a nutshell, here's
    >> how I see NSConnection and DO... properly set up, NSConnections on
    >> the server and client side can enable you to pretty much ignore the
    >> fact that two objects live in separate processes.  You'll just use
    >> regular obj-c messaging between them.  On the server side, you get
    >> a connection, assign it a root object, and "advertise" its presence:
    >>
    >> NSConnection *theConnection = [NSConnection defaultConnection];
    >> [theConnection setRootObject:myServerController];
    >> if(![theConnection registerName:@"myServerName"]){
    >> // undesirable, but unlikely
    >> }
    >>
    >> On the client side, you need to grab the server-side object (the
    >> "vended" object in the docs) like so...
    >>
    >> id myServerObject = [[NSConnection
    >> rootProxyForConnectionWithRegisteredName:@"myServerName host:nil]
    >> retain];
    >>
    >> You might typically specify a communications protocol to use (an
    >> obj-c protocol that you create defining the messages that the
    >> server object understands), and also message the server with a
    >> reference to self (the client object) so the server can hang on to
    >> a reference to it...
    >>
    >> [(NSDistantObject *)myServerObject
    >> setProtocolForProxy:@protocol(myServerProtocol)];
    >> [myServerObject setClientObject:self];
    >>
    >> (Note that "setClientObject" is something you implement yourself,
    >> can be named as desired, and its function is to retain a reference
    >> to the client object).  Now the server can send regular objective-c
    >> messages to the client object, and the client can send regular
    >> objective-c messages to the server object.  Both objects are
    >> represented by a stand-in instance of NSDistantObject in each
    >> other's address spaces.
    >>
    >> Using NSConnection as above, you really don't need any of the other
    >> classes you mentioned.
    >>
    >> Some caveats: Distributed Objects is not present in the iPhone OS,
    >> and I have encountered troubles (that did not have workarounds last
    >> I heard) when using DO with garbage collection.
    >>
    >> Also to clarify, NSNetService is not directly related to DO, but
    >> might be more familiar to you as Bonjour - it is used to discover
    >> other processes that advertise their presence on the network.
    >>
    >> Hope this helps!
    >>
    >> John
    >>
    >> Positive Spin Media
    >> http://www.positivespinmedia.com
  • On Wed, Dec 3, 2008 at 11:14 PM, Ken Tozier <kentozier...> wrote:
    > Thanks John. That cleared up a few things.
    >
    > Ultimately, what I want to do, is talk directly to a MySQL database without
    > the need for the MySQL libraries. The libraries target specific processors
    > and OS versions which makes maintenance a royal pain. I was thinking I could
    > bypass the whole library zoo by doing something ike the following
    >
    > #define DEFAULT_MYSQL_PORT_NUMBER      3306
    > #define DEFAULT_HOST_NAME      @"locahost"
    >
    > NSSocketPort    *socket                = [[NSSocketPort alloc]
    > initRemoteWithTCPPort: DEFAULT_MYSQL_PORT_NUMBER host: DEFAULT_HOST_NAME];
    > NSConnection    *connection            = [[NSConnection alloc]
    > initWithReceivePort: nil sendPort: socket];
    >
    > In tests, this seemed to connect OK, but I take it from your explanation,
    > that I would need to send objective C messages which MySQ doesn't grok. In
    > this case, would I need to set up one or both of NSInputStream,
    > NSOutputStream to send and receive data? Or would I have to go even lower
    > into BSD socked land (a la PictureBrowser) to do this sort of thing?

    NSConnection is for distributed objects and nothing else. Despite the
    name it is *not* a general-purpose IPC mechanism. As such, it only
    works for talking to other Cocoa programs (and only if they're
    prepared to accept distributed objects connections), so using it for
    MySQL is Right Out.

    If you create a pair of NSStreams with a socket then it provides you
    with essentially a direct wrapper for the BSD socket stuff. (It is so
    direct that the -read: and -write: methods have the exact same
    semantics as the read() and write() functions despite not being
    documented this way for at least one or two OS revisions.) I've found
    NSStream to be the most convenient way for dealing with sockets in a
    Cocoa app in most situations, but you can certainly feel free to hit
    the BSD layer or use one of the other free sockets wrappers if you
    prefer.

    Mike
  • Thanks Mike

    Still trying to get my head around this stuff, but here's how I
    interpret what I need to do...

    Create a connection to MySQL
    #define DEFAULT_MYSQL_PORT_NUMBER 3306
    socket = [[NSSocketPort alloc] initRemoteWithTCPPort:
    DEFAUT_MYSQL_PORT_NUMBER host: @"some host"];

    Register as the delegate of the port
    [socket setDelegate: self];

    Add to run loop
    [[NSRunLoop mainRunLoop] addPort: socket forMode:
    NSDefaultRunLoopMode];

    Here's where I lose the thread. As the delegate, do I need to implement
    - (void) handlePortMessage:(NSPortMessage *) inPortMessage

    Or, because I'm dealing with something that has no concept of
    NSPortMessage, do I need to use NSInput/NSOutput streams? If so, where
    in the process do I squeeze those in? Also very confused about which
    stream I would receive replies from MySQL (assuming I could
    successfully connect) If I send a message through an NSOutputStream,
    wouldn't MySQL send the reply back through the same stream? I don't
    see how it could do otherwise as it has no idea who the client app is,
    or how to connect and build it's own NSOutput stream with which to
    reply.

    On Dec 4, 2008, at 12:23 AM, Michael Ash wrote:

    > NSConnection is for distributed objects and nothing else. Despite the
    > name it is *not* a general-purpose IPC mechanism. As such, it only
    > works for talking to other Cocoa programs (and only if they're
    > prepared to accept distributed objects connections), so using it for
    > MySQL is Right Out.
    >
    > If you create a pair of NSStreams with a socket then it provides you
    > with essentially a direct wrapper for the BSD socket stuff. (It is so
    > direct that the -read: and -write: methods have the exact same
    > semantics as the read() and write() functions despite not being
    > documented this way for at least one or two OS revisions.) I've found
    > NSStream to be the most convenient way for dealing with sockets in a
    > Cocoa app in most situations, but you can certainly feel free to hit
    > the BSD layer or use one of the other free sockets wrappers if you
    > prefer.
    >
    > Mike
  • On Thu, Dec 4, 2008 at 1:22 AM, Ken Tozier <kentozier...> wrote:
    > Thanks Mike
    >
    > Still trying to get my head around this stuff, but here's how I interpret
    > what I need to do...
    >
    > Create a connection to MySQL
    > #define DEFAULT_MYSQL_PORT_NUMBER      3306
    > socket  = [[NSSocketPort alloc] initRemoteWithTCPPort:
    > DEFAUT_MYSQL_PORT_NUMBER host: @"some host"];
    >
    > Register as the delegate of the port
    > [socket setDelegate: self];
    >
    > Add to run loop
    > [[NSRunLoop mainRunLoop] addPort: socket forMode:
    > NSDefaultRunLoopMode];
    >
    > Here's where I lose the thread. As the delegate, do I need to implement
    > - (void) handlePortMessage:(NSPortMessage *) inPortMessage
    >
    > Or, because I'm dealing with something that has no concept of NSPortMessage,
    > do I need to use NSInput/NSOutput streams?

    Yes. NSPort is part of the Distributed Objects system. It's possible
    to use NSPort on its own, but you must use it to talk to another
    process which also uses NSPort. It is *possible* to use NSSocketPort
    to create a socket which you then communicate with using other
    techniques, but you can't use NSSocketPort directly to talk to a
    non-Cocoa app.

    > If so, where in the process do I
    > squeeze those in?

    Just replace the above code with code that creates a pair of NSStreams
    to your target.

    > Also very confused about which stream I would receive
    > replies from MySQL (assuming I could successfully connect) If I send a
    > message through an NSOutputStream, wouldn't MySQL send the reply back
    > through the same stream? I don't see how it could do otherwise as it has no
    > idea who the client app is, or how to connect and build it's own NSOutput
    > stream with which to reply.

    You'll have a pair of NSStreams which wrap the same socket. When you
    write to your NSOutputStream the data will be written to the socket,
    and when the other end writes to the socket, it will appear on your
    NSInputStream.

    Mike
  • OK. After reading the docs on NSStream, here's what I came up with.

    - (BOOL) openStreamsWithMode:(MySQLConnectMode) inMode
    {
    [NSStream getStreamsToHost: host port: port inputStream: &inStream
    outputStream: &outStream];

    if ((inStream != nil) && (outStream != nil))
    {
      connectMode  = inMode;

      [inStream retain];
      [outStream retain];

      [inStream setDelegate: self];
      [outStream setDelegate: self];

      [inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:
    NSDefaultRunLoopMode];
      [outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:
    NSDefaultRunLoopMode];

      [inStream open];
      [outStream open];

      NSLog(@"inputStream: %@, outputStream: %@", inStream, outStream);

      return YES;
    }
    else
      NSLog(@"Failed to open inputStream: %@, outputStream: %@", inStream,
    outStream);

    return NO;
    }

    - (void) stream:(NSStream *) inSender
      handleEvent:(NSStreamEvent) inEvent
    {
    NSLog(@"Entered: stream:handleEvent: with sender: %@", inSender);

    if (inSender == inStream)
    {
      switch (inEvent)
      {
      case NSStreamEventHasBytesAvailable:
        NSLog(@"NSStreamEventHasBytesAvailable");
        [self readInputStreamData];
        break;

      case NSStreamEventErrorOccurred:
        NSLog(@"NSStreamEventErrorOccurred: %@", [inStream streamError]);
        break;

      case NSStreamEventEndEncountered:
        NSLog(@"NSStreamEventEndEncountered");
        [self processStreamData];
        break;
      }

    }
    }

      I tried it out and got the following printout to the console

    > inputStream: <NSCFInputStream: 0x13d170>, outputStream:
    <NSCFOutputStream: 0x13d1e0>
    > connection: <MySQLConnection: 0x824800>
    > Entered: stream:handleEvent: with sender: <NSCFInputStream: 0x13d170>
    > NSStreamEventErrorOccurred: Error Domain=NSPOSIXErrorDomain Code=61
    "Operation could not be completed. Connection refused"
    > Entered: stream:handleEvent: with sender: <NSCFOutputStream:
    0x13d1e0>

    Which seems to make sense because MySQL requires a handshake and
    NSSocket doesn't know how to respond to that handshake. To perform the
    handshake, it seems I need to descend into BSD sockets.

    Looking at the "Picture browser" example project shows how to set up a
    socket for listening, but not how to set one up to send the initial
    connect request to a remote process

    int                        fdForListening;
    struct sockaddr_in        serverAddress;
    socklen_t                namelen            = sizeof(serverAddress);

    // In order to use NSFileHandle's acceptConnectionInBackgroundAndNotify
    // method, we need to create a file descriptor that is itself a socket,
    // bind that socket, and then set it up for listening. At this point,
    // it's ready to be handed off to acceptConnectionInBackgroundAndNotify.

    if((fdForListening = socket(AF_INET, SOCK_STREAM, 0)) > 0)
    {
    memset(&serverAddress, 0, sizeof(serverAddress));

    serverAddress.sin_family  = AF_INET;
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddress.sin_port  = 0; // allows the kernel to choose the port
    for us.

    if(bind(fdForListening, (struct sockaddr *) &serverAddress,
    sizeof(serverAddress)) < 0)
    {
      close(fdForListening);
      return;
    }

    // Find out what port number was chosen for us.
    if(getsockname(fdForListening, (struct sockaddr *) &serverAddress,
    &namelen) < 0)
    {
      close(fdForListening);
      return;
    }

    chosenPort = ntohs(serverAddress.sin_port);

    if(listen(fdForListening, 1) == 0)
    {
      handshakeSocket = [[NSFileHandle alloc] initWithFileDescriptor:
    fdForListening closeOnDealloc: YES];
    }
    }

    I gather from that, I need to set the following serverAddress fields
    differently but after looking at "in.h" none of the "INADDR_xxx" modes
    jump out at me
    serverAddress.sin_family            = AF_INET;
    serverAddress.sin_addr.s_addr    = htonl(INADDR_ANY);
    serverAddress.sin_port            = 0; // allows the kernel to choose the port
    for us.

    Which should I use "IN_CLASSA_HOST," "IN_CLASSB_HOST," other?

    How does one set up a file descriptor for an initial connect request
    to a remote process?
  • On 04 Dec 08, at 16:39, Ken Tozier wrote:
    <snip...>
    > I tried it out and got the following printout to the console
    >
    >> inputStream: <NSCFInputStream: 0x13d170>, outputStream:
    > <NSCFOutputStream: 0x13d1e0>
    >> connection: <MySQLConnection: 0x824800>
    >> Entered: stream:handleEvent: with sender: <NSCFInputStream:
    > 0x13d170>
    >> NSStreamEventErrorOccurred: Error Domain=NSPOSIXErrorDomain
    > Code=61 "Operation could not be completed. Connection refused"
    >> Entered: stream:handleEvent: with sender: <NSCFOutputStream:
    > 0x13d1e0>
    >
    > Which seems to make sense because MySQL requires a handshake and
    > NSSocket doesn't know how to respond to that handshake. To perform
    > the handshake, it seems I need to descend into BSD sockets.

    This is incorrect. A "connection refused" error in this context means
    that you're either trying to connect to a host/port which is not
    configured to accept a connection, or the host is behind a firewall
    which blocks incoming connections. In this case, it's probably the
    former. But what you're probably running into here is simply the fact
    that MySQL doesn't accept TCP connections at all by default - instead,
    it uses a UNIX domain socket in either /var/tmp/mysql.sock or /tmp/
    mysql.sock.

    More to the point, though, why are you trying to reimplement the MySQL
    client library? You haven't even gotten to the wire protocol yet,
    which I guarantee is going to pose you even more problems than just
    connecting to the server. If you're just concerned about having to
    include the library, you can link statically against the
    libmysqlclient library to avoid having to drag the shared library
    around with you. (Note, however, that libmysqlclient is licensed under
    the GPL, so you'll need to talk to Sun if you want to use it in non-
    free software.)
  • On Dec 6, 2008, at 6:45 PM, Andrew Farmer wrote:

    > This is incorrect. A "connection refused" error in this context
    > means that you're either trying to connect to a host/port which is
    > not configured to accept a connection, or the host is behind a
    > firewall which blocks incoming connections. In this case, it's
    > probably the former. But what you're probably running into here is
    > simply the fact that MySQL doesn't accept TCP connections at all by
    > default - instead, it uses a UNIX domain socket in either /var/tmp/
    > mysql.sock or /tmp/mysql.sock.

    The host and client are both on my laptop so I don't think the config/
    firewall stuff applies. I got my custom socket class working and was
    able to connect, at least up to receiving the handshake packet, using
    TCP. Not sure what Apple is doing in the guts of NSSocketPort, but my
    class is able to connect and fetch the handshake. When I try the same
    thing with NSSocketPort's file descriptor, no go.
    >
    > More to the point, though, why are you trying to reimplement the
    > MySQL client library? You haven't even gotten to the wire protocol
    > yet, which I guarantee is going to pose you even more problems than
    > just connecting to the server. If you're just concerned about having
    > to include the library, you can link statically against the
    > libmysqlclient library to avoid having to drag the shared library
    > around with you. (Note, however, that libmysqlclient is licensed
    > under the GPL, so you'll need to talk to Sun if you want to use it
    > in non-free software.)

    I love a challenge :) It's an interesting problem and I'm learning how
    to use sockets. I wouldn't have even thought of bypassing the library,
    but I stumbled across this really cool flash library that connects to
    MySQL completely via sockets (http://asql.mooska.pl/release/srcview/)
    and thought it would be cool to do something like that in Cocoa.

    The MySQL protocol isn't all that difficult. I found a good resource
    here (http://forge.mysql.com/wiki/
    MySQL_Internals_ClientServer_Protocol) The trickiest part seems to be
    scrambling the user password with the seed MySQL sends in the
    handshake. I already wrote a nice, simple packet parser to handle the
    different types of MySQL messages and am working my way through the
    password stuff.

    What I'm writing will be installed on about 50 to 100 machines and I
    have no interest in installing the client lib on all of them. I
    actually got some code working with the client lib but it broke as
    soon as it was installed on a different architecture (PowerPC) and OS
    version (10.4 vs 10.5) These four combinations of OS and processors
    are a given and I can't do anything about that. Each configuration
    requires a client lib specifically compiled for it and I don't want to
    support 4 different versions of my app or the support calls when they
    do a clean install or an upgrade and suddenly my app stops working.
    With my own sockets, I'll only ever have to worry about MySQL protocol
    changes which are much less frequent than MySQL updates.
previous month december 2008 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today