设为首页 加入收藏

TOP

基于 GCDAsyncSocket,简单实现类似《你猜我画》的 socket 数据传输(一)
2017-10-12 12:55:29 】 浏览:10021
Tags:基于 GCDAsyncSocket 简单 实现 类似 《你猜我画》 socket 数据传输

一、前言

  • Socket
    • Socket 是对 TCP/IP 协议的封装,其中IP协议对应为网络层,TCP 协议对应为传输层,而我们常用的HTTP协议,是位于应用层,在七层模型中HTTP协议是基于 TCP/IP 的,我们想要使用 TCP/IP 协议,则要通过 Socket
  • Socket 编程用途(其他待补充)
    • 长连接
    • 端到端的即时通讯
  • Socket 和 Http(来源网络)
    • socket 一般用于比较即时的通信和实时性较高的情况,比如推送,聊天,保持心跳长连接等,http 一般用于实时性要求不那么高的情况,比如信息反馈,图片上传,获取新闻信息等。

二、类似《你猜我画》简易效果说明

  • 效果(分别是模拟器和手机截图)

  • 工作中碰到类似需求,但没找到类似的成熟的第三方框架,只有先看看原理性的东西了。其实也就基于 socket 即时传输图片数据、笔画数据,还有聊天文字,也可以拓展做其他的指令控制
  • 没有做注册登录,没有做用户管理,只是简单原理性的探讨
  • 基于 GCDAsyncSocket 框架进行,关于 GCDAsyncSocket 的介绍可自行了解

三、服务端部分代码

  • 直接用 mac 程序作为服务端
    • Server 类
/*!
 @method  开启服务
 @abstract 开启服务器 TCP 连接服务
 */
- (void)startServer {

    self.serverSocket = [[GCDAsyncSocket alloc]initWithDelegate:self
                                                    delegateQueue:dispatch_get_main_queue()];
                                                    NSError *error = nil;
    [self.serverSocket acceptOnPort:5555
                              error:&error];
    if (error) {
        NSLog(@"服务开启失败");
    } else {
        NSLog(@"服务开启成功");
    }

}
#pragma mark - GCDAsyncSocketDelegate
/*!
 @method  收到socket端连接回调
 @abstract 服务器收到socket端连接回调
 */
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
    [self.clientSocketArray addObject:newSocket];
    [newSocket readDataWithTimeout:-1
                               tag:self.clientSocketArray.count];
}
/*!
 @method  收到socket端数据的回调
 @abstract 服务器收到socket端数据的回调
 */
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    // 直接进行转发数据
    for (GCDAsyncSocket *clientSocket in self.clientSocketArray) {
        if (sock != clientSocket) {

            [clientSocket writeData:data
                withTimeout:-1
                        tag:0];
        }
    }
    [sock readDataWithTimeout:-1
                          tag:0];

}
  • main 中

    int main(int argc, const char * argv[]) {
    @autoreleasepool {
    
        Server *chatServer = [[Server alloc]init];
        [chatServer startServer];
        // 开启主运行循环
        [[NSRunLoop mainRunLoop] run];
    }
    return 0;
    }

四、移动端部分代码

  • 基于 GCDAsyncSocket 的接受数据代理方法及发送数据方法
  • 图片数据的发送
// 回调 发送图片
    __weak typeof(self) weakSelf = self;
    bgImgView.block = ^(UIImage *img) {

        weakSelf.drawView.drawImg = img;
        // image
        NSData *imgData = UIImageJPEGRepresentation(weakSelf.drawView.drawImg, 0.2);
        NSMutableData *dat = [NSMutableData data];
        [dat appendData:imgData];
        // 拼接二进制数据流的结束符
        NSData *endData = [@"$" dataUsingEncoding:NSUTF8StringEncoding];
        [dat appendData:endData];
        // 发送数据
        [weakSelf.clientSocket writeData:dat
                         withTimeout:-1
                                 tag:111111];

    };
  • 图片二进制数据的传输是基于流的,一段一段的,避免断包缺包等问题,需要拼接结束符,图片数据结束
  • 图片数据的接受接受
        // 拼接数据 转成图片

       [self.socketReadData appendData:data];

       NSData *endData = [data subdataWithRange:NSMakeRange(data.length -1, 1)];

       NSString *end= [[NSString alloc] initWithData:endData
                                            encoding:NSUTF8StringEncoding];

       if ([end isEqualToString:@"$"]) {

           UIImage *tmpImg = [UIImage imageWithData:self.socketReadData];

           self.drawView.drawImg = tmpImg;

           [self.drawView setNeedsDisplay];

           [self.clientSocket readDataWithTimeout:-1
                                              tag:111111];
           // 拼完图片 恢复默认
           self.socketReadData = nil;

       }
  • 画布笔画数据的传输
    • 因为传输的是二进制数据,所以采取将贝塞尔曲线转换成 CGPoint 坐标数组,再加上线宽和线的颜色,最后组成一个字典,转换为二进制进行传输
    • 考虑到坐标点在不同屏幕上需要适配,因此需要把当前手机端的屏幕高宽一起传输
/*!
 @method  发送路径
 @abstract 通过socket 发送路径信息
 */
- (void)sendPath {
    // path 坐标点及 转换
    NSArray *points = [(UIBezierPath *)self.dataModel.path points];
    NSMutableArray *tmp = [NSMutableArray array];
    for (id value in points) {
        CGPoint point = [value CGPointValue];
        NSDictiona
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS 创建OpenGL 环境的思考 下一篇用keychain这个特点来保存设备唯..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目