IOS网络篇4之Socket通信(传递图片和基本数据)

来源:互联网 发布:react.js starter kit 编辑:程序博客网 时间:2024/05/29 14:32

紧接这一篇

IOS网络篇3之IOS底层网络架构详解

在使用socket进行通信之前我们首先来认识几个东东:

CFReadStreamRef

CFWriteStreamRef

来看看水果公司官方的解释:

CFReadStream provides an interface for reading a byte stream either synchronously or asynchronously. You can create streams that read bytes from a block of memory, a file, or a generic socket。

CFStream是一个输入输出数据流,可以实现和内存、文件、socket之间的数据交互。因此我们这里使用Socket必然要使用这个对象。

再来看看另外两个对象:

NSInputStream

NSOutputStream

NSStream is an abstract class for objects representing streams. Its interface is common to all Cocoa stream classes, including its concrete subclasses NSInputStream and NSOutputStream.

这个对象实现了和底层数流的交互,可以和CFStream实现无阻碍连接。

socket实现网络通信主要由两个方法组成:

- (void)initNetworkCommunication

{

   CFReadStreamRef readStream;

   CFWriteStreamRef writeStream;

//  建立与服务器的连接,设置ip地址,PORT端口,返回输入输出数据流。

   CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.1.134",PORT, &readStream, &writeStream);

//  __bridge_transfer 一般用于将core foundation转化为foundation

   _inputStream = (__bridge_transferNSInputStream *)readStream;

    _outputStream = (__bridge_transferNSOutputStream

                     *)writeStream;

//  设置接收设备的委托代理

    [_inputStreamsetDelegate:self];

    [_outputStreamsetDelegate:self];

//  将数据输入输出流添加到run loop中。

    [_inputStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]

                           forMode:NSDefaultRunLoopMode];

    [_outputStreamscheduleInRunLoop:[NSRunLoopcurrentRunLoop]

                            forMode:NSDefaultRunLoopMode];

//  打开输入输出流

    [_inputStreamopen];

    [_outputStreamopen];

    

}


//  对各种事件的响应

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

   NSString *event;

   switch (streamEvent) {

//      没有事件发生

        caseNSStreamEventNone:

            event =@"NSStreamEventNone";

           break;

//      成功打开流

        caseNSStreamEventOpenCompleted:

            event = @"NSStreamEventOpenCompleted";

           break;

//      数据可读,在读取数据的时候使用

        caseNSStreamEventHasBytesAvailable:

            event = @"NSStreamEventHasBytesAvailable";

           if (flag ==1 && theStream ==_inputStream) {

               NSMutableData *input = [[NSMutableDataalloc]init];

               uint8_t buffer[1024000];

               long len;

//              是否数据可读。如果可读那么执行循环读取。

               while([_inputStreamhasBytesAvailable])

                {

//                  将数据读取到缓冲区并返回数据的长度。

//                  查看这个

                   NSLog(@"buffer=%ld",sizeof(buffer));

                    len = [_inputStreamread:buffermaxLength:sizeof(buffer)];

                   NSLog(@"xxxxx=%ld",len);

                   if (len >0)

                    {

//                      如果数据有效,那么将数据追加到input中。

                        [inputappendBytes:bufferlength:len];

                    }

                }

               NSLog(@"input length = %d",[inputlength]);

               UIImage *image = [UIImageimageWithData:input];

               UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);

//              Data进行解码转化为字符串。

//                NSString *resultstring = [[NSString alloc] initWithData:input encoding:NSUTF8StringEncoding];

//                NSLog(@"接收:%@",resultstring);

//                _message.text = resultstring;

//                NSLog(@"image write swuccess!");

            }

           break;

//          写入数据流

        caseNSStreamEventHasSpaceAvailable:

            event = @"NSStreamEventHasSpaceAvailable";

           if (flag ==0 && theStream ==_outputStream) {


//              按照NSData *data的形式,传递NSData数据,注意这里传递的数据的长度也是[data length]+1

//              传递的数据类型是[data bytes]

               NSString *sendmessage  =@"hello郑微serve!";

//              这里将字符串转化为 nsdata

                NSData *data = [[NSDataalloc]initWithData:[sendmessagedataUsingEncoding:NSUTF8StringEncoding]];

                [_outputStreamwrite:[databytes]maxLength:[datalength]+1];

                [_outputStreamclose];

            }

           break;

//      读取流发生错误时候调用

        caseNSStreamEventErrorOccurred:

            event = @"NSStreamEventErrorOccurred";

            [selfclose];

           break;

//      流结束的时候调用。

        caseNSStreamEventEndEncountered:

            event = @"NSStreamEventEndEncountered";

            NSLog(@"Error:%d:%@",[[theStreamstreamError]code], [[theStreamstreamError]localizedDescription]);

           break;

       default:

            [selfclose];

            event =@"Unknown";

           break;

    }

    NSLog(@"event------%@",event);

}

注意这里的数据传输还可以通过下面三个方法来实现:

//              方法按照UInt8 buff[] = "Hello Server!";传递数据。传递数据的位数是实际长度+1.

//              比如这个是13个字节,实际传递的数据长度是14个字节。

                //需要写入的数据空间

                UInt8 buff[] = "Hello Server!";

                [_outputStream write:buff maxLength: strlen((const char*)buff)+1];

                 //必须关闭输出流否则,服务器端一直读取不会停止,

                [_outputStream close];

                 */

//                *****************************************

//                /*

//              方法按照NSData *data的形式,传递NSData数据,注意这里传递的数据的长度也是[data length]+1

//              传递的数据类型是[data bytes]

               NSString *sendmessage  =@"hello郑微serve!";

//              这里将字符串转化为 nsdata

                NSData *data = [[NSDataalloc]initWithData:[sendmessagedataUsingEncoding:NSUTF8StringEncoding]];

                [_outputStreamwrite:[databytes]maxLength:[datalength]+1];

                [_outputStreamclose];

//                */

//              ********************************************

//              方法nsdata转化为UInt8然后再传递

//              UInt8 *p = (UInt8*) [data bytes];

//              [_outputStream write:p maxLength:[data length]+1];

//              注意带中文的采用NSUTF8StringEncoding中文编码

//              不带中文的采用NSASCIIStringEncoding ascii编码


0 0
原创粉丝点击