iOS开发-socket

ios socket即时通讯

2018-07-12  本文已影响18人  落枫猿

首先理一下网络通讯三要素

  1. IP地址(主机名)
  1. 端口号
  1. 传输协议(通讯的规则)

1.Socket到底是什么东西?以下这幅流程图表示运行过程

屏幕快照 2018-07-10 下午5.43.01.png

总结:socket其实就是:用来操作某个IP上的某个端口来达到点对点通讯效果,本身就是一个抽象的东东,通讯就是通过socket来交互,可以面向TCP和UDP两种连接

2.Socket终端使用案例:

  1. 新建两个终端控制台
  2. 第一台输入命令: nc -l 6969 (开启nc命令,使用6969端口,充当服务器端)
  3. 第二台输入命令:nc 127.0.0.1 6969 (两台的端口保持一致,充当客户端)
  4. 最后两台终端就可以实现通讯了,可以相互发送消息

以上案列采用的 “nc”命令,可以用来检测本地GCP连接

3.Socket 代码实际运用

socket是成双成对的出现

  1. 导入框架
#import <sys/socket.h>
#import <arpa/inet.h>
#import <netinet/in.h>
  1. 定义端口号和ip
static const char *serve_ip = "127.0.0.1";  //ip
static const short serve_port = 6969;    //port

3.定义socket

@property (nonatomic,assign) int clientSockt; //定义socket
/**  */
@property (nonatomic,strong) UITextField *msgTextFiled; //创建消息文本
/**  */
@property (nonatomic,strong) NSThread *thread;
  1. 创建socket , 连接服务器端
//创建socket
-(void)initSockt{
    /**
     参数
     domain : 协议域 ,AF_INET ->IPV4
     type: Socket 类型,SOCK_STREAM(流/TCP)/SOCK_DGRAM(报文/UDP)
     protocol: IPPROTO_TCP(如果写0,那么就会自动选择)
     
     返回值
     socket
     */
    _clientSockt = socket(AF_INET, SOCK_STREAM, 0);
 
    
    
    //连接IP地址和服务端
    struct sockaddr_in serverAddr;
    //赋值长度
    serverAddr.sin_len = sizeof(serverAddr);
    
    serverAddr.sin_family = AF_INET;
    
    //IP地址
    inet_aton(serve_ip, &serverAddr.sin_addr);
    
    //端口号
    serverAddr.sin_port = htons(serve_port);
    
    int connetResult = connect(_clientSockt,(const struct sockaddr *)&serverAddr, sizeof(serverAddr));
    if (connetResult == 0) {
        NSLog(@"连接成功");
        //开启一个线程模拟
        self.thread = [[NSThread alloc]initWithTarget:self selector:@selector(receveAction) object:nil];
        [self.thread start];
    }
    else{
        NSLog(@"连接失败 %d",connetResult);
        return;
    }
}
  1. 接收消息
-(void)receveAction{
    /**
     参数
     1.客户端socket
     2.接受内容缓冲区地址
     3.接受内容缓存区长度
     4.接受方式,0表示阻塞,必须等待服务器返回数据
     
     返回值
     如果超过,则返回读入的字节数,失败则返回SOCKET_ERROR
     */
  while (1) {
        uint8_t buffer[1024];//空间,准备数据
        
        size_t recvlen = recv(_clientSockt, buffer, sizeof(buffer), 0);//等待着获的数据
        NSLog(@"接受到多少数据%ld",recvlen);
        //解析数据(获取到的服务器数据)
        NSData *date = [NSData dataWithBytes:buffer length:recvlen];
        NSString *str  = [[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding];
        NSLog(@"接收到的内容:%@",str);
    }
}
  1. 接下来,我们来利用终端来模拟服务器,向我们的app发送消息,上面我们已经说过,怎么使用终端来建立一个服务器端口,建立连接。好了,这个时候,把我们的App跑起来吧,看看有什么神奇的效果
    在终端输入:
nc -l 6969 //这是建立服务器端口,再把APP跑起来,这时应该就会发现控制台打印“连接成功”。这时,就可以任意发送消息了
123456 //这是发送的消息
1213131SAS //这是发送的消息

这时,在app控制台打印出效果

2018-07-12 11:26:12.459423+0800 Socket[1232:116451] 连接成功
2018-07-12 11:26:23.504420+0800 Socket[1232:116570] 接受到多少数据7
2018-07-12 11:26:23.504659+0800 Socket[1232:116570] 接收到的内容:123456

2018-07-12 11:26:26.944561+0800 Socket[1232:116570] 接受到多少数据11
2018-07-12 11:26:26.944768+0800 Socket[1232:116570] 接收到的内容:1213131SAS

ok,一切尽在不言中

  1. 接受消息,我们这边已经搞定,那么接下来我们再来搞定发送消息

首先创建一个按钮、一个输入文本框,点击按钮,发送文本框内的字符串,调用以下方法,实现发送

-(void)sendAction:(NSString *)msg{
    //3.发送数据
    /**
     参数
     1.客户端socket
     2.发送内容地址(指针)
     3.发送内容长度
     4.发送内容标志,一般为0
     
     返回值
     如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
     
     */
    //void * 表示万能指针(以下两种都可以)
    //    NSString *msg = @"hello";
    //    const char * msg = @"hello";
    ssize_t sendLen = send(_clientSockt, msg.UTF8String, strlen(msg.UTF8String), 0);
    NSLog(@"发送了 %ld字节",sendLen);
    
}

发送成功后,这时在终端上就显示出了,刚刚发送的消息

  1. 正所谓,有始就有终,我们还剩下最后一步,那就是断开连接,如果不用了,就得把链接断开,节约资源
-(void)disConnection{
    //关闭数据连接
    [self.thread cancel];
    close(_clientSockt);
}

4. socket 实际运用

是实际开发过程中,对于一般的小型聊天,都采用“环信、融云、LeanClould”,但是对于主供消息聊天的就不可能采用这些三方公司的,因为价钱太高,所以就会引用一些三方框架:

  1. 基本socket 原生, CocoaAsyncSocket
  1. 基于WebSocket , SocketRocket,SRWebSocket
  1. 基于MQIT, MQTTKit 、MQTTClient
  1. 基于XMPP,XMPPFrameWork
上一篇 下一篇

猜你喜欢

热点阅读