Socket简析与iOS实现

作者: 无忌不悔 | 来源:发表于2018-05-04 17:11 被阅读262次
WebSocket

Socket的基本概念

1.定义

网络上两个程序通过一个双向通信连接实现数据交互,这种双向通信的连接叫做Socket(套接字)。

2.本质

网络模型中应用层与TCP/IP协议族通信的中间软件抽象层,是它的一组编程接口(API),也即对TCP/IP的封装。TCP/IP也要提供可供程序员做网络开发所用的接口,即Socket编程接口。

Socket的位置

3.要素

Socket是网络通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信的必须的五种信息:

  • 连接使用的协议
  • 本地主机的IP地址
  • 本地进程的协议端口
  • 远程主机的IP地址
  • 远程进程的协议端口

4.特性

Socket可以支持不同的传输协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接;同理,当使用UDP协议进行连接时,该Socket连接就是一个UDP连接。
多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

5.连接

建立Socket连接至少需要一对套接字,分别运行于服务端(ServerSocket)和客户端(ClientSocket)。套接字直接的连接过程氛围三个步骤:

Step 1 服务器监听

服务端Socket始终处于等待连接状态,实时监听是否有客户端请求连接。

Step 2 客户端请求

客户端Socket提出连接请求,指定服务端Socket的地址和端口号,这时就可以向对应的服务端提出Socket连接请求。

Step 3 连接确认

当服务端Socket监听到客户端Socket提出的连接请求时作出响应,建立一个新的进程,把服务端Socket的描述发送给客户端,该描述得到客户端确认后就可建立起Socket连接。而服务端Socket则继续处于监听状态,继续接收其他客户端Socket的请求。

iOS客户端Socket的实现

1. 数据流方式

- (IBAction)connectToServer:(id)sender {
    // 1.与服务器通过三次握手建立连接
    NSString *host = @"192.168.1.58";
    int port = 1212;
    
    //创建一个socket对象
    _socket = [[GCDAsyncSocket alloc] initWithDelegate:self
                                         delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    
    NSError *error = nil;
    
    // 开始连接
    [_socket connectToHost:host
                    onPort:port
                     error:&error];
    
    if (error) {
        NSLog(@"%@",error);
    }
}


#pragma mark - Socket代理方法
// 连接成功
- (void)socket:(GCDAsyncSocket *)sock
didConnectToHost:(NSString *)host
          port:(uint16_t)port {
    NSLog(@"%s",__func__);
}


// 断开连接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock
                  withError:(NSError *)err {
    if (err) {
        NSLog(@"连接失败");
    } else {
        NSLog(@"正常断开");
    }
}


// 发送数据
- (void)socket:(GCDAsyncSocket *)sock
didWriteDataWithTag:(long)tag {
    
    NSLog(@"%s",__func__);
    
    //发送完数据手动读取,-1不设置超时
    [sock readDataWithTimeout:-1
                          tag:tag];
}

// 读取数据
-(void)socket:(GCDAsyncSocket *)sock
  didReadData:(NSData *)data
      withTag:(long)tag {
    
    NSString *receiverStr = [[NSString alloc] initWithData:data
                                                  encoding:NSUTF8StringEncoding];
    
    NSLog(@"%s %@",__func__,receiverStr);
}

2.基于第三方开源库CocoaAsyncSocket

2.1客户端通过地址和端口号与服务端建立Socket连接,并写入相关数据。

- (void)connectToServerWithCommand:(NSString *)command
{
    _socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    [_socket setUserData:command];
    
    NSError *error = nil;
    [_socket connectToHost:WIFI_DIRECT_HOST onPort:WIFI_DIRECT_PORT error:&error];
    if (error) {
        NSLog(@"__connect error:%@",error.userInfo);
    }
    
    [_socket writeData:[command dataUsingEncoding:NSUTF8StringEncoding] withTimeout:10.0f tag:6];
}

2.2 实现CocoaAsyncSocket的代理方法

#pragma mark - Socket Delegate

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSLog(@"Socket连接成功:%s",__func__);
}

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    if (err) {
        NSLog(@"连接失败");
    }else{
        NSLog(@"正常断开");
    }
    
    if ([sock.userData isEqualToString:[NSString stringWithFormat:@"%d",SOCKET_CONNECT_SERVER]])
    {
        //服务器掉线 重新连接
        [self connectToServerWithCommand:@"battery"];
    }else
    {
        return;
    }
}

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"数据发送成功:%s",__func__);
    //发送完数据手动读取,-1不设置超时
    [sock readDataWithTimeout:-1 tag:tag];
}

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"读取数据:%s %@",__func__,receiverStr);
}

粘包与半包

关于粘包和半包,请看iOS 详解Socket编程粘包、半包处理

相关文章

  • Socket简析与iOS实现

    Socket的基本概念 1.定义 网络上两个程序通过一个双向通信连接实现数据交互,这种双向通信的连接叫做Socke...

  • IOS开发_Socket通讯

    1、socket简介; 2、IOS中socket的实现; 1、socket简介; 1.1 概念:套接字(s...

  • react native资料

    React Native 学习资源精选仓库(汇聚知识,分享精华) React Native IOS集成与原理简析 ...

  • 使用OC二进制流进行发送消息

    //ios这里实现socket的链接,使C语言//1.与服务器通过三次握手实现链接NSString *host =...

  • 即时通讯

    iOS即时通讯,从入门到“放弃”?socket的半包,粘包与分包的问题iOS 处理socket粘包问题iOS___...

  • 0. Socket学习资料汇总

    Socket理论知识 iOS Socket理论知识 关于iOS socket都在这里了 iOS Socket T...

  • Socket.IO on Objective-C

    Socket.IO on iOS 基础与简介GitHub下载地址(swift版本):socket.io-clien...

  • iOS web交互

    iOS极简模式实现Webview网页图片原生预览 IOS中 使用JavaScriptCore 实现OC与JS的交互...

  • iOS socket 浅析与简单实现

    (原创, 请勿转载) 有好多童鞋面对socket大有无从下手之感, 我就随便说说 socket 翻译过来叫套接字,...

  • iOS Socket编程(二)TCP三次握手,四次挥手

    iOS Socket编程(一)基本概念iOS Socket编程(二)TCP三次握手,四次挥手iOS Socket编...

网友评论

  • 谢谢生活:补的粘包和半包处理非常好
    无忌不悔:@谢谢生活 哈哈 别人写的,是挺好的,大家一起学习吧,还是要看书,网上的东西不够系统
  • 谢谢生活:粘包处理,数据解析,心跳链接呢?亲
    无忌不悔:@谢谢生活 感谢,最近正在看Socket相关,正愁不能深入了解,看样子要多看书了
    谢谢生活:@无忌不悔 我也不太清楚,粘包是 : 消息头+消息体 头里面是消息的长度,解析的时候先解析头再获取头后面长度的数据,这就是一个单独的消息。 心跳链接就是一个定时器 注意前后台切换的时候 开启和关闭心跳
    无忌不悔:@谢谢生活 求教~

本文标题:Socket简析与iOS实现

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