ios socket即时通讯

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

  1. IP地址(主机名)
  • 网络设备标示
  • 本地回环地址:127.0.0.1 主机名:localHost
  1. 端口号
  • 用于标识进程的逻辑地址,不同进程的标示
  • 有效端口:0 ~ 65535
  • 其中 0 ~ 1024 由系统使用或者保留端口
  1. 传输协议(通讯的规则)
  • TCP
  • UDP

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

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

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

  • 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
  • 就是BSD Socket,处理了很多协议
  • 是基于传输层封装的一套框架
  1. 基于WebSocket , SocketRocket,SRWebSocket
  • 用于浏览器的长连接协议
  1. 基于MQIT, MQTTKit 、MQTTClient
  • 适用订阅的消息机制,列如:滴滴打车地图上的小车轨迹
  • 适用于物联网,传输层更小,低带宽,性能更优
  • 位于应用层的聊天协议
  1. 基于XMPP,XMPPFrameWork
  • 缺点,是基于XML的数据来传输的
  • 位于应用层的聊天协议
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容