iOS 网络通信的方法

iOS设备的网络通信的方法,有如下两个大类:

1、使用socket的方式进行通信。

2、使用asynsocket类库进行通信。


两种方法当中,我觉得asynsocket更好,因为是别人已经封装好的类库,比较稳定。但是对于直接使用socket的通信方法我倒是觉得很灵活。因为控制都是自己在做的事情。


先列举集中不同的使用方法:


1、直接使用socket的方式。

TCP为利,对于TCP来说,是要区分服务端和客户端的。服务端:通常的方法是服务端启动后监听,是否有客户端连接,如果有连接,则建立与客户端的通信。客户端的方法通常是连接服务端,当连接成功之后,就希望发送数据了。


客户端:

CFSocketContext sockContext;

CFSocketRef  cfsock;

sockContext.info = self;

sockContext.copyDescription = 0;

cfsock = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketConnectCallBack, MyCallBack, &sockContext);


// 这个地方是个关键的地方,就是建立一个ip地址,然后使的客户端可以向服务端发起连接。

NSString *strAddress = @"192.168.1.1";

if (cfsock != nil)

{

    struct sockaddr_in addr4;

    memset(&addr4,0,sizeof(addr4));

    addr4.sin_len = sizeof(addr4);

    addr4.sin_family = AF_INET;

    addr4.sin_port = htons(1230);

    addr4.sin_addr.s_addr = inet_addr( [strAddress UTF8String] );

    CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8*)&addr4, sizeof(addr4));

    CFSocketConnectToAddress(cfsock, address, -1);

}


// 发起连接之后,需要将runloop的过程,也就是消息的过程加入到当前线程当中。这样当有事件发生时,会调用对应的方法。

CFRunLoopRef crun = CFRunLoopGetCurrent();// CFRunLoopGetMain();

CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfsock, 0);

CFRunLoopAddSource(crun, source, kCFRunLoopCommonModes);

CFRelease(source);


回调函数:当连接成功之后的处理如下:

static void MyCallBack (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)

{

    if (data != NULL)

    {

        NSLog(@"传输失败!");

    }

    SocketTestAppDelegate *client = (SocketTestAppDelegate*)info;

    [client performSelectoInBackground:@selector(readstream) withObject:nil];

}


- (void) readstream

{

    char buffer[1024];

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    while (recv(CFSocketGetNative(cfsock),buffer,sizeof(buffer),0))

    {

        

    }

    [pool release];

}


//  如果希望直接向服务器写内容的话,采用如下的方法。

- (void) sendstream

{

    NSString *stringtosend = @"hello everyone";

    const char *data = [stringtosend UTF8String];

    send(CFSocketGetNative(cfsock),data,strlen(data)+1,0);

}


服务器端的程序:

CFSocketRef socketserver;

int setupSocket()

{

    socketserver = CFSocketCreate(kCFAllocatorDefault,PF_INET,SOCK_STREAM,IPPROTO_TCP,kCFSocketAcceptCallBack,myaccept,NULL);

    int optval = 1;

    setsockopt(CFSocketGetNative(socketserver), SOL_SOCKET, SO_REUSEADDR, (void*)&optval,sizeof(optval));

    struct sockaddr_in addr4;

    memset(&addr4,0,sizeof(addr4));

    addr4.sin_len = sizeof(addr4);

    addr4.sin_family = AF_INET;

    addr4.sin_port = htons(10);

    addr4.sin_addr.s_addr=htonl(INADDR_ANY);

    CFDataRef  address = CFDataCreate(kCFAllocatorDefault, (UInt8*)&addr4, sizeof(addr4));

    CFSocketSetAddress(socketserver, address);

    CFRunLoopRef cfRunloop = CFRunLoopGetCurrent();

    CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socketserver, 0);

    CFRunLoopAddSource(cfRunloop, source, kCFRunLoopCommonModes);

    CFRelease(source);

}


// 服务端的socket建立之后,就需要接受client的连接,因此建立连接的回调函数。

static void myaccept (CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)

{

    if (callbackType == kCFSocketAcceptCallBack)

    {

        // 如果对端连接成功的话,是可以获取对端的名称和socket的。

        CFSocketNativeHandle nativesockethandle = *(CFSocketNativeHandle*)data;

        uint8_t name[100];

        socklen_t namelen = 100;

        getpeername(nativesockethandle, (struct sockaddr *)name, &namelen);

        

        // 除此以外,更重要的是获取输入流 输出流,

        CFReadStreamRef iStream;

        CFWriteStreamRef oStream;

        // 创建一个可读写的socket连接

        CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativesockethandle, &iStream, &oStream);

        CFStreamClientContext streamcontext=

        {

            0,NULL,NULL,NULL

        };

        // 注册两种事件!

        CFReadStreamSetClient(iStream, kCFStreamEventHasBytesAvailable, readStream, &streamcontext);

        CFReadStreamSetClient(iStream, kCFStreamEventCanAcceptBytes, writeStream, &streamcontext);

        

        // 加入到循环当中!

        CFReadStreamScheduleWithRunLoop(iStream, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);

        CFWriteStreamScheduleWithRunLoop(oStream, CFRunLoopGetCurrent(),kCFRunLoopCommonModes);

        

        CFReadStreamOpen(iStream);

        CFWriteStreamOpen(oStream);

    }

}


void readStream(CFReadStreamRef stream,CFStreamEventType eventType, void *clientCallBackInfo)

{

    UInt8 buff[255];

    CFReadStreamRead(stream, buff, 255);

    printf("received: %s", buff);

}


void writeStream (CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo)

{

    // outputStream = stream;

    char *str = "nihao"; CFWriteStreamWrite(outputStream, str, strlen(line) + 1);

}


另一种方法是使用NSStream的方式构建客户端,然后发送和接受内容。

- (void)startClient

{

    host = [NSHosthostWithAddress:@"192.168.201.24"];//hostWithName:@"www.apple.com"];

    [NSStreamget StreamsToHost:host port:4242 inputStream:&inStream outputStream:&outStream];

    

    if ((inStream == nil) || (outStream == nil))

    {

        NSLog(@"Error: Failed to create streams!") ;

        [selfrelease];

    }

}


- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode

{

    switch (eventCode)

    {

        case NSStreamEventHasBytesAvailable:

        {

            NSMutableData *input = [[NSMutableDataalloc] init];

            uint8_t buffer[1024];

            intlen;

            while ([inStream hasBytesAvailable])

            {

                len = [inStream read:buffer maxLength:sizeof(buffer)];

                if (len > 0)

                {

                    [input appendBytes:buffer length:len];

                }

            }

            self._resultdata = input;

            self._resultstring = [[NSStringalloc] initWithData:input encoding:NSUTF8StringEncoding];

            [input release];

            break;

        }

        case NSStreamEventEndEncountered:

            [selfcloseStream];

            break;

        case NSStreamEventHasSpaceAvailable:

        case NSStreamEventErrorOccurred:

        {

            NSLog(@"Error:%@:%@",[[aStream streamError] code], [[aStream streamError] localizedDescription]);

        }

        case NSStreamEventOpenCompleted:

        case NSStreamEventNone:

        default:

            break;

    }

}


- (void)closeStream

{

    [inStream close];

    [outStream close];

    [inStream removeFromRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];

    [outStream removeFromRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];

    [inStream setDelegate:nil];

    [outStream setDelegate:nil];

    [inStream release];

    [outStream release];

    inStream = nil;

    outStream = nil;

}


- (void)openStream

{

    [inStream retain];

    [outStream retain];

    [inStream setProperty:NSStreamSocketSecurityLevelSSLv3forKey:NSStreamSocketSecurityLevelKey];

    [outStream setProperty:NSStreamSocketSecurityLevelSSLv3forKey:NSStreamSocketSecurityLevelKey];

    NSMutableDictionary *sslSettings;

    sslSettings = [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kCFBooleanFalse,kCFStreamSSLValidatesCertificateChain,kCFBooleanFalse,kCFStreamSSLIsServer,nil];

    CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, sslSettings);

    [inStream setDelegate:self];

    [outStream setDelegate:self];

    [inStream scheduleInRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];

    [outStream scheduleInRunLoop:[NSRunLoopcurrentRunLoop] forMode:NSDefaultRunLoopMode];

    [inStream open];

    [outStream open];

}


- (int)writeString:(NSString *)string

{

    NSData *messageAsData = [string dataUsingEncoding:NSASCIIStringEncoding];

    return[outStream write:(c*****t uint8_t *)[messageAsData bytes] maxLength:[messageAsData length]];

}


- (int)writeBytes:(char *)buffer length:(unsigned int)len

{

    return [outStream write:(c*****t uint8_t *)buffer maxLength:len];

}


@end


转自:http://blog.csdn.net/dongdongdongjl/article/details/7776377

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值