Use of "Go" ios streaming (stream)

Source: Internet
Author: User

Transferred from: http://southpeak.github.io/blog/2014/07/17/ioszhong-liu-stream-de-shi-yong/

Streams provide an easy way to exchange data between different and medium, which is device-independent. A stream is a sequential sequence of bits that are transmitted serially in a communication path. From an encoding standpoint, the stream is unidirectional, so the stream can be an input stream or an output stream. In addition to file-based streaming, other forms of flow are not available, and once consumed, the data cannot be retrieved from the Stream object again.

The cocoa contains three stream-related classes: Nsstream, Nsinputstream, and Nsoutputstream. Nsstream is an abstract base class that defines the underlying interfaces and properties of all stream objects. Nsinputstream and Nsoutputstream inherit from Nsstream, which implements the default behavior of the input stream and output stream. Describes the application scenario for a flow:



See, Nsinputstream can get data from files, sockets, and NSData objects, Nsoutputstream can write data to files, sockets, memory caches, and NSData objects. These three classes mainly deal with some of the lower-level tasks.

The Stream object has some properties associated with it. Most properties are used to handle network security and configuration, collectively known as SSL and socks proxy information. Two of the more important attributes are:

    1. Nsstreamdatawrittentomemorystreamkey: Allows output stream queries to write data to memory
      Nsstreamfilecurrentoffsetkey: Allows you to manipulate the read and write location of a file-based stream



You can assign a proxy object to a Stream object. If not specified, the Stream object acts as its own proxy. The stream object calls the only proxy method stream:handleevent: To handle flow-related events:

    1. For an input stream, there is a data-readable event available. We can use the Read:maxlength: method to get the data from the stream
      For the output stream, the data event is ready to be written. We can use the Write:maxlength: method to write data to the stream



The stream objects in the cocoa correspond to the stream objects in the core Foundation. We can convert each other through the toll-free bridging method. Nsstream, Nsinputstream and Nsoutputstream correspond to Cfstream, Cfreadstream and Cfwritestream respectively. But the two are not exactly the same. The Core Foundation typically uses callback functions to process data. In addition, we can subclass Nsstream, Nsinputstream, and Nsoutputstream to define properties and behaviors, while stream objects in the core Foundation cannot be extended.

Here are some of the basic concepts of iOS streaming, and we'll show you how to use the stream in the following section, first to see how to read the data from the stream.

Reading data from the input stream

Reading data from a Nsinputstream stream consists of the following steps:

    1. Create and initialize a Nsinputstream instance from the data source
      Put the stream object in a run loop and open the stream
      Handling the events that flow objects send to their agents
      When no more data can be read, the stream object is closed and destroyed.
      Prepare the Stream object



To use a nsinputstream, you must have a data source. The data source can be files, NSData objects, and network sockets. Once created, we set its proxy object, put it into the run loop, and open the stream. Code Listing 1 shows the preparation process.

Proxy Listing 1

Copy Code
  1. -(void) Setupstreamforfile: (NSString *) path
  2. {
  3. Nsinputstream *inputstream = [[Nsinputstream alloc] initwithfileatpath:path];
  4. Inputstream.delegate = self;
  5. [InputStream Scheduleinrunloop:[nsrunloop Currentrunloop] formode:nsdefaultrunloopmode];
  6. [InputStream Open];
  7. }



When a stream object is placed in a run loop and there is a stream event (with readable data), the Stream object sends a stream:handleevent: message to the proxy object. Before we open the stream, we need to call the Scheduleinrunloop:formode: method of the stream object to avoid blocking the proxy object when there is no data to read. What we need to make sure is that the stream object is put into the correct run loop, which is put into the run loop of the thread where the stream event occurred.

Handling Flow Events

After opening the stream, we can use the Streamstatus property to view the state of the stream, use the Hasbytesavailable property to detect whether there is readable data, and use Streamerror to see the errors that occur during the stream processing.

Once opened, the stream will continue to send the Stream:handleevent: Message to the proxy object until the end of the stream. This message receives a Nsstreamevent constant as a parameter to identify the type of event. For Nsinputstream objects, the main event types are nsstreameventopencompleted, Nsstreameventhasbytesavailable and nsstreameventendencountered. Usually we are more interested in nsstreameventhasbytesavailable. Agent Listing 2 demonstrates the process of getting data from a stream

Proxy Listing 2

Copy Code
  1. -(void) stream: (Nsstream *) Astream handleevent: (nsstreamevent) EventCode
  2. {
  3. Switch (EventCode) {
  4. Case Nsstreameventhasbytesavailable:
  5. {
  6. if (!data) {
  7. data = [Nsmutabledata data];
  8. }
  9. uint8_t buf[1024];
  10. unsigned int len = 0;
  11. Len = [(Nsinputstream *) Astream read:buf maxlength:1024]; Reading data
  12. if (len) {
  13. [Data appendbytes: (const void *) BUF Length:len];
  14. }
  15. }
  16. Break
  17. }
  18. }



When an error occurs during nsinputstream processing of a stream, it stops streaming and produces a nsstreameventerroroccurred event to the proxy. We handle this event in the same way as the proxy method above.

Clean up Stream objects

When Nsinputstream reads to the end of the stream, a nsstreameventendencountered event is sent to the proxy, and the proxy object should destroy the stream object, which should correspond to the creation time, and code Listing 3 demonstrates the process of closing and releasing the Stream object.

Proxy Listing 3

  copy code
  1. -(void) stream: (Nsstream *) aSt Ream handleevent: (nsstreamevent) EventCode
  2. {
  3.     switch (eventcode) {
  4. Li>        case nsstreameventendencountered:
  5.          {
  6.              [astream Close];
  7.             [astream removeFromRunLoop:[ Nsrunloop Currentrunloop] Formode:nsdefaultrunloopmode];
  8.             astream = nil;
  9.         }
  10.             break;
  11.     }
  12. }



Writing data to the output stream

Similar to reading data from an input stream, writing data to the output stream requires the following steps:

    1. Creates and initializes a Nsoutputstream instance with the data to be written, and sets the proxy object
      Place the stream object in the run loop and open the stream
      Handling events in a Stream object sent to a proxy object
      If the Stream object writes data to memory, the data is fetched by requesting the Nsstreamdatawrittentomemorystreamkey property
      When no more data is available for writing, the flow object is processed



The basic process and the input stream read, we mainly introduce different places

The locations where data can be written include files, c caches, program memory, and network sockets.

    1. The Hasspaceavailable property indicates whether there is room to write data
      In Stream:handleevent: Mainly handles the Nsstreameventhasspaceavailable event, and calls the Write:maxlength method of the stream to write the data. Code Listing 4 illustrates this process.
      If the target of the Nsoutputstream object is applied memory, the data in the stream may need to be fetched from memory in the Nsstreameventendencountered event. We will invoke the Propertyforkey: property of the Nsoutputstream object and specify key to Nsstreamdatawrittentomemorystreamkey to get the data.



Proxy Listing 4
-(void) stream: (Nsstream *) Astream handleevent: (nsstreamevent) EventCode
{
Switch (EventCode) {
Case Nsstreameventhasspaceavailable:
{
uint8_t *readbytes = (uint8_t *) [data mutablebytes];
Readbytes + = Byteindex;
int data_len = [data length];
unsigned int len = (data_len-byteindex >= 1024)? 1024x768: (Data_len-byteindex);
uint8_t Buf[len];

(void) memcpy (buf, Readbytes, Len);

len = [Astream write: (const uint_8 *) BUF Maxlength:len];
Byteindex + = Len;
Break
}
}
}

It is important to note that when the agent receives the Nsstreameventhasspaceavailable event without writing any data to the stream, the agent will no longer receive the event from the run loop until the Nsoutputstream object receives more data. The run loop then restarts the Nsstreameventhasspaceavailable event.

round robin of Flow

In the process of stream processing, in addition to putting the stream into the run loop to handle the flow events, the convection can also be round-robin. We put the process of streaming data into a loop and constantly ask the stream whether there is available data for reading (hasbytesavailable) or available space for writing (hasspaceavailable) in the loop. When we process to the end of the stream, we jump out of the loop to end the stream operation.

The specific process is shown in Listing 5

Code Listing 5

Copy Code
  1. -(void) CreateNewFile {
  2. Nsoutputstream *ostream = [[Nsoutputstream alloc] inittomemory];
  3. [OStream Open];
  4. ??? uint8_t *readbytes = (uint8_t *) [data mutablebytes];
  5. uint8_t buf[1024];
  6. int len = 1024;
  7. while (1) {
  8. if (len = = 0) break;
  9. if ([OStream hasspaceavailable])
  10. {
  11. (void) strncpy (buf, Readbytes, Len);
  12. Readbytes + = Len;
  13. if ([OStream write: (const uint8_t *) BUF maxlength:len] = =-1)
  14. {
  15. [Self Handleerror:[ostream streamerror]];
  16. Break
  17. }
  18. [Byteswritten Setintvalue:[byteswritten Intvalue]+len];
  19. Len = ([Data length]-[Byteswritten intvalue] >= 1024x768): [Data length]-[Byteswritten intvalue]);
  20. }
  21. }
  22. NSData *newdata = [OStream Propertyforkey:nsstreamdatawrittentomemorystreamkey];
  23. if (!newdata) {
  24. NSLog (@ "No data written to memory!");
  25. } else {
  26. [Self processdata:newdata];
  27. }
  28. [OStream Close];
  29. [OStream release];
  30. OStream = nil;
  31. }



The problem with this approach is that it blocks the current thread until the end of the stream process, before proceeding with the subsequent operation. This problem is particularly serious when dealing with network sockets, and we must wait for the server data to return before proceeding. Therefore, it is generally recommended to use the Run loop method to handle flow events.

Error handling

When an error occurs in the stream, the processing of the streaming data is stopped. A Stream object cannot be used for a read or write operation when an error occurs, although it can be queried for its state before it is closed.

The Nsstream and Nsoutputstream classes will inform you of the occurrence of the error in several ways:

Copy Code
  1. If the stream is placed in the run loop, the object sends a nsstreameventerroroccurred event to the stream:handleevent of the proxy object: in the method
  2. At any time, you can call the Streamstatus property to see if an error occurred (return nsstreamstatuserror)
  3. If you return-1 when you write data to the Nsoutputstream object by calling Write:maxlength:, a write error occurs.



Once the error is determined, we can call the Streamerror property of the stream object to see the details of the error. Here we no longer cite examples.

Set up the socket stream

In iOS, the Nsstream class does not support connecting to a remote host, fortunately Cfstream support. As already mentioned, the two can be converted to each other by toll-free bridging. With Cfstream, we can call the Cfstreamcreatepairwithsockettohost function and pass the host name and port number to get a cfreadstreamref and a cfwritestreamref to communicate, Then we can convert them to Nsinputstream and Nsoutputstream objects to handle.

We will discuss the specific process in detail at a later stage.

Reference

Stream Programming Guide

Use of "Go" ios streaming (stream)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.