IOS 网络链接之一二

AsyncSocket

这个开源网络连接库用起来很简单,很方便

对于客户端来说 思路很简单:

1,链接到目的地。

[socket connectToHost:@"www.baidu.com" onPort:80 error:nil];//tcp 协议

回调 - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port

2,设置读属性。

[socket readDataWithTimeout:-1 tag:3];

回调 - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

3,向目的地发送消息。

[socket writeData:[[ self makeHttpHeader:@"www.baidu.com"] dataUsingEncoding:NSUTF8StringEncoding] withTimeout:1 tag:2];

回调 - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

简单的列出3个方法。更多的方法可以看原文件,每种方法都有tag值,方便区分和使用异步操作。


这里给出拼接http头的方法,忘记是那位高人写的了,方便测试。

#define HTTPMETHOD @"GET"
#define HTTPVERSION @"HTTP/1.1"

#define HTTPHOST @"Host"

#define KENTER @"\r\n"

#define KBLANK @" "


-(NSMutableString*)makeHttpHeader:(NSString*) hostName
{
    
    NSMutableString *header = [[NSMutableString alloc] init];
    
    [header appendFormat:HTTPMETHOD];
    
    [header appendFormat:KBLANK];
    
    [header appendFormat:@"/index.html"];
    
    [header appendFormat:KBLANK];
    
    [header appendFormat:HTTPVERSION];
    
    [header appendFormat:KENTER];
    [header appendFormat:HTTPHOST];
    [header appendFormat:@":"];
    [header appendFormat:@"%@",hostName];
    [header appendFormat:KENTER];
    [header appendFormat:KENTER];
    
    return header;
}

BSD Socket

bsd socket 创建和使用的思路和 AsyncSocket 的使用思路大体一样的,稍微复杂些

1,创建socket

 sockfd = socket(AF_INET, SOCK_STREAM, 0))   //传入参数和返回值转载了一片高手的文章,有介绍

2,链接目的地
connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr));

其中参数如下:

 struct sockaddr_in their_addr;

struct hostent *host = gethostbyname([hostName UTF8String]);
    their_addr.sin_addr = *(struct in_addr*)(*(host->h_addr_list));
    their_addr.sin_family = AF_INET;
    their_addr.sin_port = htons(80);
    bzero(&(their_addr.sin_zero), 8);

3,发送数据
send(sockfd, [data bytes], [data length], 0);

其中参数如下:

NSMutableString* httpContent = [self makeHttpHeader:@"www.baidu.com"];

NSData *data = [httpContent dataUsingEncoding:NSISOLatin1StringEncoding];

4,接受数据

recv(sockfd, readBuffer, sizeof(readBuffer);

其中参数如下:

char readBuffer[512];

while((br = recv(sockfd, readBuffer, sizeof(readBuffer), 0))>0)



CFSocket

ios 封装了 CFSocket,其使用方法和其他的socket思路差不多

1,创建socket

CFSocketContext socketContext;
    bzero(&socketContext, sizeof(socketContext));
    socketContext.info = self;
    CFSocketRef _socket;
    _socket = CFSocketCreate(kCFAllocatorDefault,
                             PF_INET,//协议族
                             SOCK_STREAM, //socket类型数据包
                             IPPROTO_TCP, //协议tcp
                             kCFSocketDataCallBack | kCFSocketConnectCallBack | kCFSocketReadCallBack,//回调类型
                             &_cfsocketCallback,//回调函数
                             &socketContext);    
    //必须加入消息循环队列,否则不能回调
    CFRunLoopSourceRef  listenSourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), listenSourceRef, kCFRunLoopCommonModes);

2,链接到目的地

CFSocketError error;
    error = CFSocketConnectToAddress(_socket, _address, 5);//链接超时时间5秒

其参数如下:

    struct hostent *host = gethostbyname([@"www.baidu.com" UTF8String]);
    struct sockaddr_in newaddress;
    newaddress.sin_family = AF_INET;
    newaddress.sin_port = htons(80);
    newaddress.sin_addr = *(struct in_addr *)*(host->h_addr_list);


    CFDataRef _address = CFDataCreate(kCFAllocatorDefault, (void*)&newaddress, sizeof(struct sockaddr_in));

3,发送数据

error =  CFSocketSendData(_socket, _address, (CFDataRef)[[ self makeHttpHeader:@"www.baidu.com"] dataUsingEncoding:NSUTF8StringEncoding], 20);


这里给出回调函数

void _cfsocketCallback(CFSocketRef inCFSocketRef, CFSocketCallBackType inType, CFDataRef inAddress, const void* inData, void* inContext )
{//回调函数
    NSLog(@"inType==%d",(int)inType);
    if (inData!=NULL) {
        NSLog(@"inDataLength====%d",(int)CFDataGetLength(inData));
    }
    
    NSString * str = nil;
    str = [[[NSString alloc] initWithData:inData encoding:NSISOLatin1StringEncoding] autorelease];
    NSLog(@"%@,",str);
    
    
    if(!inContext)
        return;
    
    switch(inType)
    {
        case kCFSocketDataCallBack:
            //Incoming data will be read in chunks in the background and the callback is called with the data argument being a CFData object containing the read data.
            NSLog(@"kCFSocketDataCallBack");
            if (inData!=NULL)
            {
                int lenth = (int)CFDataGetLength(inData);
                if (lenth == 0)
                {// 连接断开
                    NSLog(@"连接断开");
                }
                else
                { //收到数据
                    NSLog(@"收到数据");
                }
            }
            
            break;
            
        case kCFSocketReadCallBack:
            
            NSLog(@"kCFSocketReadCallBack");
            // he callback is called when data is available to be read or a new connection is waiting to be accepted. The data is not automatically read; the callback must read the data itself.
            
            break;
            
        case kCFSocketAcceptCallBack:
        {
            NSLog(@"kCFSocketAcceptCallBack");
            // New connections will be automatically accepted and the callback is called with the data argument being a pointer to a CFSocketNativeHandle of the child socket. This callback is usable only with listening sockets.
            break;
        }
        case kCFSocketConnectCallBack:
            
            NSLog(@"kCFSocketConnectCallBack");
            //If a connection attempt is made in the background by calling CFSocketConnectToAddress or CFSocketCreateConnectedToSocketSignature with a negative timeout value, this callback type is made when the connect finishes
            break;
            
        default:
            break;
    }
}

CFStream

cfstream 分为两种read 和write

其实是创建输入输出流,然后进行读写,如下:

CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
                                       (CFStringRef)@"www.baidu.com",
                                       80,
                                       &readStream,
                                       &writeStream);
    CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    CFWriteStreamScheduleWithRunLoop(writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);

    CFStreamClientContext readclient ={0, NULL, NULL, NULL} ;
    CFReadStreamSetClient(readStream, kCFStreamEventOpenCompleted|
                          kCFStreamEventHasBytesAvailable|
                          kCFStreamEventCanAcceptBytes|
                          kCFStreamEventErrorOccurred |
                          kCFStreamEventEndEncountered , &readCallBack, &readclient);
    CFStreamClientContext writeclient = {0, NULL, NULL, NULL} ;
    CFWriteStreamSetClient(writeStream, kCFStreamEventOpenCompleted|
                          kCFStreamEventHasBytesAvailable|
                          kCFStreamEventCanAcceptBytes|
                          kCFStreamEventErrorOccurred |
                          kCFStreamEventEndEncountered , &writeCallBack, &writeclient);
    
    CFReadStreamOpen(readStream);
    CFWriteStreamOpen(writeStream);
    CFWriteStreamWrite(writeStream, [[[ self makeHttpHeader:@"www.baidu.com"] dataUsingEncoding:NSUTF8StringEncoding] bytes], 1024);


回调函数如下:

void readCallBack (CFReadStreamRef stream, CFStreamEventType eventType,void *clientCallBackInfo)
{
    switch (eventType) {
        case kCFStreamEventOpenCompleted:
            NSLog(@"kCFStreamEventOpenCompleted");
            break;
        case kCFStreamEventHasBytesAvailable:
            NSLog(@"kCFStreamEventHasBytesAvailable");
            UInt8 buff[255];
            CFReadStreamRead(stream, buff, 255);
            NSLog(@"--%s",buff);
            break;
        case kCFStreamEventCanAcceptBytes:
            NSLog(@"kCFStreamEventCanAcceptBytes");
            break;
        case kCFStreamEventErrorOccurred:
            NSLog(@"kCFStreamEventErrorOccurred");
            
            break;
        case kCFStreamEventEndEncountered:
            NSLog(@"kCFStreamEventEndEncountered");
            break;
        default:
            break;
    }
    
}
void writeCallBack( CFWriteStreamRef stream, CFStreamEventType eventType,void *clientCallBackInfo )
{
    
}


文档上给出句话,如下:CFWriteStream is “toll-free bridged” with its Cocoa Foundation counterpart, NSOutputStream.
其实 可以对应转换成NSOutputStream,和NSInputStream。

对于NSOutputStream,和NSInputStream 用气来比较简单,不介绍了



NSURLConnection

这个用起来会简单些,如下:

NSURLRequest * requese = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://wwww.baidu.com"]];
    NSURLConnection * contion = [[NSURLConnection alloc] initWithRequest:requese delegate:self];
    [contion start];

然后设置代理方法就可以了。


ASIHTTP

这个用的比较多,也简单。



其实对于网络链接,没有特殊的需求使用封装好的,还是要方便的多的。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值