您的位置:首页 > 理论基础 > 计算机网络

iOS 通过GCDAsyncSocket建立tcp链接

2015-09-15 17:09 531 查看
最近辗转到了ios开发当中。记录下一下最近开发的东西

这次开发的目的是建立一个tcp链接向服务器发送消息,然后读取服务器返回的消息

在这附上GCDAsyncSock的git地址可以下载下来使用,同时附带了很多例子,

https://github.com/robbiehanson/CocoaAsyncSocket

1:引入GCDAsyncSock.h和GCDAsyncSock.m当项目中

2:建立tcp链接,tcp链接因为只需要创建一次可以写在类的init中

  //创建socket,ps当然你可以先用isConnected判断一下是否链接

   GCDAsyncSocket *reqsocket;  //监听套接字

    reqsocket = [[GCDAsyncSocketalloc]
initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];

    //建立连接
   NSError *err=nil;

    if (![reqsocketconnectToHost:@"192.168.1.1"onPort:80error:&err])
{

        NSLog(@"connect remote server failed,%@",err);
    }

3:(首先明确整个TCP链接是采用的异步的方法而不是同步)

3.1写方法(个人理解有点类似于发送写指令)

NSString *sendmMsg =@"POST /seconfigAT HTTP/1.1\r\nHost: 192.168.1.1\r\nConnection: keep-alive\r\nAuthorization: Basic YWRtaW46YWRtaW4=\r\nContent-Length: 11\r\n\r\nwifi_Scan=1\r\n\r\n";

[reqsocketwriteData:data
withTimeout:-1tag:0];
解释一下其中的参数,timeout就是超时时间,后面有一个tag刚开始始终搞不明白tag作用,简单说来就是为了区分是那一次读写,比如第一次写的时候你设置了一个tag=0那么在写的回调函数中你就可以通过tag来区分是那一次的写回调的。。

3.2读方法

    //因为tcp消息包可能是连续发送为了区分返回的包可以对包进行分割,此处用</html>分割,这样的坏处是如果分隔符填写错误将不会返回。。。

        NSData* sperateData = [@"</html>"dataUsingEncoding:NSUTF8StringEncoding];
        [reqsocketreadDataToData:sperateData
withTimeout:-1
tag:0];
当然你还可以读取固定长度的
        [reqsocket readDataToLength:<#(NSUInteger)#> withTimeout:<#(NSTimeInterval)#> buffer:<#(NSMutableData *)#> bufferOffset:<#(NSUInteger)#> tag:<#(long)#>]
也有更简单的形式,就不多说了有兴趣的看文档

4:主要回调函数

回调函数很多主要常用的有以下几个

//链接成功之后回调
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString
* )host port:(uint16_t)port;

//读成功之后回调
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data
withTag:(long)tag;

//写成功后回调的函数
 -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;

//链接断开的时候回调
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError
*)err;
至于还有什么别的可以参考文档

5:读数据的时候可以继续监听服务器返回的数据
        [reqsocketreadDataToData:sperateDatawithTimeout:-1tag:0]

6:需不需要断开链接(ps这个需不需要看个人)

     [reqsocketdisconnect];

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
重要的事情说三遍 ,千万不要随便从word复制字符串,千万不要随便从word复制字符串,千万不要随便从word复制字符串,这个错误让我调了两天,word复制的字符串中空格会包含不可见字符。
这一次的开发其实是一个http请求完全可以用mknetwork,更简单。。。。因为刚刚开始所以勿喷

<span style="font-size:14px;">-(void)createConnect{
//创建socket嵌套字
reqsocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
//建立连接
NSError *err=nil;
if (![reqsocket connectToHost:@"192.168.17.254" onPort:80 error:&err]) {
NSLog(@"connect remote server failed,%@",err);
}
}</span>
然后我在创建成功之后需要向服务器发送一个写请求

//链接成功之后回调
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString * )host port:(uint16_t)port{
if (writeTag==0) {
//链接成功之后会自动发送向服务器的写请求
NSString *sendmMsg = @"POST /goform/ser2netconfigAT HTTP/1.1\r\nHost: : keep-alive\r\nAuthorization: Basic YWRtaW46QzI5V1JBUlRKSUdXSDlHOUZCRUQ=\r\nContent-Length";
NSLog(@"%@",sendmMsg);
NSData *data = [sendmMsg dataUsingEncoding:NSUTF8StringEncoding];
//向服务器发送写请求
[reqsocket writeData:data withTimeout:-1 tag:0];
}
else if (writeTag==1){

NSData *data = [sendmMsgConnect dataUsingEncoding:NSUTF8StringEncoding];
//向服务器发送写请求
[reqsocket writeData:data withTimeout:-1 tag:1];
}
}然后在写成功后的回调函数中我再向服务发送读请求
//写成功后回调的函数
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
if (tag==0) {
NSData* sperateData = [@"</html>" dataUsingEncoding:NSUTF8StringEncoding];
//发送写请求
[reqsocket readDataToData:sperateData withTimeout:-1 tag:0];
}
else if (tag==1){

}
}


然后在读成功之后的回调函数中我在获取服务器返回的数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
if (tag==0) {
//获取读回的数据
scannerInfo = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"scanner wifi datas is :%@",scannerInfo);
NSData* sperateData = [@"</html>" dataUsingEncoding:NSUTF8StringEncoding];
//继续监听
[reqsocket readDataToData:sperateData withTimeout:-1 tag:0];
}
else if(tag==1){

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息