iOS之GCDAsyncSocket(TCP)

作者: CrazySteven | 来源:发表于2016-07-03 10:58 被阅读4089次

上周周末的时候发烧了,就担误了写博客,这周就多写点吧。

这次主要讲下Socket,关于它的三次握手、四次挥手什么的已经写的很多了,也写的很好,我就不写了。但注释代码时会穿插些Socket原理进去,当然也会提供Demo。

TCP Socket Server

#import "GCDAysncSocket.h"遵守协议<GCDAsyncSocketDelegate>

创建一个socket:
self.serverSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
监听端口:
    NSError * error = nil;
    [self.serverSocket acceptOnPort:[self.portTextField.text integerValue] error:&error];
等待连接://此为GCDAsyncSocket代理方法
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
    //这里需要对Socket的工作原理进行一点解释,当Socket accept一个连接服务请求时,将生成一个新的Socket,即此处的newSocket。在此可查看newSocket.connectedHost和newSocket.connectedPort等参数,并通过新的socket向客户端发送一包数据后会关闭你一开始创建的socket(self.serverSocket),接下来你都将使用newSocket(我将此保存为self.clientSocket)
    self.clientSocket = newSocket;
}
连接失败://此为GCDAsyncSocket代理方法
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err;
{
    NSLog(@"连接失败,要怎么做,你自己看着办吧");
}
连接成功,发送数据
//注意此处使用的是上面的newSocket
[self.clientSocket writeData:[self.sendTextView.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
    //我创建了一个Socket单例,这里只讨论Socket,单例创建可看Demo
    SocketManager * socketManager = [SocketManager sharedSocketManager];
    [socketManager.mySocket readDataWithTimeout:-1 tag:0];
对发送的数据根据tag进行管理://此为GCDAsyncSocket代理方法
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    NSLog(@"可通过参数中的tag值管理发送的数据,想怎么管理,您看着办");
}
连接成功,接收数据
    //同样使用的是newSocket
    [self.clientSocket readDataWithTimeout:-1 tag:0];
接收数据成功,处理数据://此为GCDAsyncSocket代理方法
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSLog(@"接收到消息%@,要怎么处理,您看着办",data);
}

这是服务器Demo,欢迎大家Star


TCP Socket Client

#import "GCDAysncSocket.h"遵守协议<GCDAsyncSocketDelegate>

创建Socket:
self.clientSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
连接服务器:
    NSError * error = nil;
    [self.clientSocket connectToHost:self.ipTextField.text onPort:[self.portTextField.text integerValue] error:&error];
连接成功://此处为GCDAsyncSocket代理方法
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    //创建的socket单例
    SocketManager * socketManager = [SocketManager sharedSocketManager];
    socketManager.mySocket = sock;
}
连接失败://此处为GCDAsyncSocket代理方法
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    NSLog(@"自己看着办");
}
连接成功,发送数据
    [self.clientSocket writeData:[self.sendTextView.text dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
连接成功,接收数据
    [self.clientSocket readDataWithTimeout:-1 tag:0];
接收数据成功,处理数据://此处为GCDAsyncSocket代理方法
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSLog(@"接收到消息%@,要怎么处理,您看着办",data);
}

到此处就结束了,大家可以发现,客户端这边从头到尾都是使用的一个Socket,并没有出现新的Socket,这一点是需要注意的。客户端Demo,欢迎大家Star.

版权声明:本文为 Crazy Steven 原创出品,欢迎转载,转载时请注明出处!

相关文章

网友评论

  • 等这姑娘老在我心里:问一下 服务端怎么进行重启 或者重新进行监听呢,现在退到后台再回到前台就不管用了
  • Hanson_HSS:你好,客户端传一个zip文件过来,知道怎么处理吗??
    CrazySteven:@Hanson_HSS 有第三方解压的
  • 玉盏:朋友你这个粘包啊
    CrazySteven:@玉盏 哦哦,你可以手动设置发送频率啊
    玉盏:@CrazySteven 我说的是粘包。。。粘包是指发送端发送的包速度过快,到接收端那边多包并成一个包的现象,比如发送端连续10次发送1个字符'a',因为发送的速度很快,接收端可能一次就收到了10个字符'aaaaaaaaaa',这就是接收端的粘包
    CrazySteven:100%自己动手敲的。
  • f0110219d1aa:请问一下,我服务端一直监听失败是什么原因?
    CrazySteven:有可能IP不在一个网段吧。。。先试试能不能ping通
  • FokHiuFai:这个demo都是只能一对一吗 我用2个客户端连的话 先连的那个就会断开
    CrazySteven:@FokHiuFai :+1:
    FokHiuFai:@CrazySteven 后面改了下可以了 要把每个新添加的socket用一个全局的数组保存下来才可以
    CrazySteven:@FokHiuFai http://www.cocoachina.com/bbs/read.php?tid-336205.html创建多个socket即可,我没连过多个,应该是可以的。
  • 小羊孩子:你好,测试可以使用一台手机一个模拟器来调试吗?手机是客户端,填写的ip 是电脑上的ip吗?端口自己随便写吗? 刚接触。大神说说吧
    CrazySteven:@小羊孩子 我测的都是正常的,一个电脑一个手机。。。
    小羊孩子:@CrazySteven 我昨天测试了, 服务端demo收不到socket。但是客户端跟我们后台服务器可以通信
    CrazySteven:@小羊孩子 可以
  • 小羊孩子:挺好。支持
  • 630c5eeb35d3:您好,想问下有没有一种情况是在连接成功的协议方法-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port中,调用了[self.asyncSocket readDataWithTimeout:-1 tag:0]; 读取数据方法成功以后,导致点击其他按钮读取数据方法不可用
    630c5eeb35d3:@CrazySteven 那可以解决吗?因为readData是要读取数据的,或者我该怎么查询错误呢?
    CrazySteven:我没有遇到过,但我认为是有可能会出现的,因为我开发中做出某些bug以后会导致一些莫名其妙的错误。这些错误并不会使你的app闪退,但会使你的app某些功能用不了。
  • 4f70f079e295:你的manager 是干什么用的
    CrazySteven:@井岗山 管理socket的
  • 4f70f079e295:为什么我这个总是显示断开链接呢?
    等这姑娘老在我心里:把对象换成Property属性看看
  • 开发者老岳:这个demo为啥还得手动接收消息,不是应该自动接收消息吗?
    开发者老岳:好使,感谢 :smile:
    CrazySteven:@老岳_ 你可以使用- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;这个方法自己去实现自动接收消息。比如你可以在连接成功后调用一次接收消息方法,然后在- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag这个方法里再调用接收消息方法,很简单的。
  • 凯文Kevin21:服务器端Demo代码有问题,客户端demo没问题。测试了一下
    凯文Kevin21:@CrazySteven 然后我换成了别人的server Demo可以收到消息。 你的demo客户端没有问题。你可以去试一下看
    凯文Kevin21:@CrazySteven 我是测试的:2台 iphone5s 都是连接的同一个wifi , 1台手机上跑客户端,1台手机上跑服务器端,开始监听端口号。 客户端向服务端通过ip+端口号发送消息, 服务端那台手机收不到消息。。。
    CrazySteven:@七秒小鱼人 有什么问题?
  • 清眸如画:自己封装的吧
    CrazySteven:@约定一生 GCDAsyncSocket不是我封装的。

本文标题:iOS之GCDAsyncSocket(TCP)

本文链接:https://www.haomeiwen.com/subject/tstcjttx.html