zoukankan      html  css  js  c++  java
  • Socket学习

    之前一直没做过socket相关的项目,在智能家居领域socket应用还是比较广泛的,所以一直想着学习socket相关知识,正好最近项目不是很忙,就想着补一补之前要学但是没学的东西。

    1. iOS里的socket主要是基于CFSocket来做的,原生socket是用c语言写的,调用的方式有点复杂,所以一般很少会用到,可以看这个链接了解一下即可

    2. 这里主要说一下对原生CFSocket进行封装过的第三方库GCDAsyncSocket,这个库应用还是比较广泛的,github上的star数量达到了11.8k。(在github上要搜索CocoaAsyncSocket才能搜到,直接搜GCDAsyncSocket的话搜到的都是各种demo)

    3. GCDAsyncSocket的简单使用,直接把GCDAsyncSocket.hGCDAsyncSocket.m复制进项目即可使用

    4. Server代码:

      //初始化
      self.connectedSockets = [[NSMutableArray alloc] initWithCapacity:1];
      self.serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
      //开始监听端口
      [self.serverSocket acceptOnPort:port error:&error];
      
        #pragma mark - GCDAsyncSocketDelegate
        //有客户端连接时会调用
        - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
            NSLog(@"%s", __func__);
            //保持对newSocket的引用,使用newSocket来发送和读取数据,newSocket和sock有相同的代理
            //下面几个代理方法中的sock即为此处的newSocket
            [self.connectedSockets addObject:newSocket];
            NSData *data = [@"欢迎连接!" dataUsingEncoding:NSUTF8StringEncoding];
            [newSocket writeData:data withTimeout:-1 tag:0];
        }
        //写入数据完成回调
        - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
            NSLog(@"%s", __func__);
            [sock readDataWithTimeout:-1 tag:tag];
        }
        //读取数据完成回调
        - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
            NSLog(@"%s", __func__);
            NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"string: %@", message);
            NSString *sendString = [@"你说:" stringByAppendingString:message];
            NSData *sendData = [sendString dataUsingEncoding:NSUTF8StringEncoding];
            [sock writeData:sendData withTimeout:-1 tag:tag];
        }
      
       在调试过程中遇到的问题:   
       1. 没有设置`delegatequeue`报错,初始化时设置为`dispatch_get_main_queue`即可
       2. 客户端发来的数据没有读取到,需要显示的调用`readDataWithTimeout`方法来读取数据
      
    5. Client代码:

      //初始化
      self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
      //开始连接
      NSError *error;
      [self.clientSocket connectToHost:hostIP onPort:hostPort.integerValue error:&error];
      
        #pragma mark - GCDAsyncSocketDelegate
        //成功连接到服务器
        - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
            NSLog(@"%s", __func__);
            NSData *data = [@"已经连接!" dataUsingEncoding:NSUTF8StringEncoding];
        		[sock writeData:data withTimeout:-1 tag:0];
        }
        //写入数据完成
        - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
            NSLog(@"%s", __func__);
            [sock readDataWithTimeout:-1 tag:tag];
        }
        //读取数据完成
        - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
            NSLog(@"%s", __func__);
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"string: %@", string);
            [sock readDataWithTimeout:-1 tag:0];
        }
      
       在调试过程中遇到的问题:
       1. 收到的数据不是最新的,而是上一次发的数据,需要在`didReadData`方法的最后,再调用`readDataWithTimeout`即可
      
    6. 用到的调试工具
      刚开始连接运行两个demo,分别在手机和电脑上测试,一直连不上,不知道什么问题,百度之后发现了sockit这个调试工具。使用homebrew安装,就可以在mac上调试socket,可以分别模拟客户端和服务端进行调试,非常方便。

  • 相关阅读:
    包装类
    项目基础架构搭建
    开发环境的搭建和Shell编程
    Linux系统概述和编程基础
    java.lang.ExceptionInInitializerError
    mybatis中文文档
    如何造轮子
    Application Server was not connected before run configuration stop, reason: Unable to ping server at localhost:1099
    JDK 1.7与JDK 1.8版本的完美切换
    JDBC连接步骤
  • 原文地址:https://www.cnblogs.com/shenyuiOS/p/13996724.html
Copyright © 2011-2022 走看看