Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to make a NSStream instance reusable?

bobgreenbobgreen Posts: 7New Users
edited June 2009 in iOS SDK Development
Hello everyone, I'm new to socket stream developing.

I've prepared the nsstream class and make it work fine with sending and receiving data with a server application(written by C#).

But I can't send and receive data again and again through the same stream connection. It means, I have to CLOSE and RELEASE the first stream instance and ALLOC a new one to send and receive new data. It's obviously too complicated to work with a multi-threads server application. Since I only can determine one client connection with its IP and PORT, if I create a new connection with the following code, the PORT will change and I will never know if it's a new client or not.
[NSHost hostWithAddress:ADDRESS port:PORTinputStream:&inStream outputStream:&outStream];
(I don't know if hostWithAddress still work in real iPhone with OS3.0?:confused:)

And I find out that, if I CLOSE the instream and outstream and then OPEN them again, it doesn't work.
In Apple's SDK, they said:
Close
Closing the stream terminates the flow of bytes and releases system resources that were reserved for the stream when it was opened. If the stream has been scheduled on a run loop, closing the stream implicitly removes the stream from the run loop. A stream that is closed can still be queried for its properties.
Open
A stream must be created before it can be opened. Once opened, a stream cannot be closed and reopened.

I'm thinking about Jume's post in this link(click me). He said:
1) created a Communicator class (subclass of NSObject) that sets NSInputStream and NSOutputStream objects for connecting to TCP socket
2) created a protocol CommunicatorDelegate in this communicator class for delegation
3) set the NSStream delegate method - (void)stream: (NSStream *)theStream handleEvent: (NSStreamEvent)streamEvent to handle reading and writing to socket
4) I'm using a Singleton instance method for this Communicator class so that I can access socket from anywhere in my application.
So I think, there must be a way to realize what I need. But I can't find any sample code to realize it. Apple's sample code which I think can only send and receive once in one instance(maybe I'm wrong:()
Post edited by bobgreen on

Replies

  • bobgreenbobgreen Posts: 7New Users
    edited June 2009
    Here's the code which I use to OPEN and CLOSE a stream.
    -(void)closeStream{
        [inStream close];
        [outStream close];
        [inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [inStream setDelegate:nil];
        [outStream setDelegate:nil];
        [inStream release];
        [outStream release];
        inStream = nil;
        outStream = nil;
    }
     
    -(void)openStream{
        [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];
    }
    
    
    And the code to send data.
    -(int)writeString: (NSString *) string 
    {
        NSData *messageAsData = [string dataUsingEncoding:NSUTF8StringEncoding];
        int i = [outStream write: (const uint8_t *) [messageAsData bytes] maxLength: [messageAsData length]];
        return i;
    }
    
  • bobgreenbobgreen Posts: 7New Users
    edited June 2009
    Need help~

    I'm thinking about never close the stream to keep them alive, will it be OK?
  • bobgreenbobgreen Posts: 7New Users
    edited June 2009
    I researched the EchoServer and EchoClient demo sample.
    It seems we really don't need to close a stream until we finish everything with it.
    Now the problem is, how to determine each message's end between server and client?
    In C#, we can use
    messageData.ToString().IndexOf("<EOF>") > -1
    
    to determine the end.
    What about Obj-C?
    I think I can't use only one byte to determine the end.
Sign In or Register to comment.