iOS网络编程之Socket

1、套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

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

简单来说,Socket更像是对传输层的简单封装,使的开发者可以更好的使用一些协议从而实现不用进程和应用之间的通讯。

以下是通讯示意图

通讯示意图

这里关于TCP/UDP协议不过多介绍,TCP需要通过著名的三次握手进行连接,不懂的朋友可以看看这篇文章->计算机网络传输层知识点全覆盖

2、iOS Socket应用场景

Socket 使用长连接进行通讯,凡是一个来回网络请求解决不了问题的都会用socket。例如常见的IM类应用、音视频通话等。

与之对应的是HTTP连接,HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。例如我们下载图片、浏览微信朋友圈等。

3、常用的socket类型

常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。

流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;
数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。

4、iOS使用的socket编程的方式有哪些?

第一种: BSD Socket

BSD Socket 是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制。而iOS系统其实本质就是UNIX,所以可以用,但是比较复杂。

第二种:CFSocket

CFSocket是苹果提供给我们的使用Socket的方式,但是用起来还是会不太顺手。当然想使用的话,可以细细研究一下。

第三种:CocoaAsyncSocket

CocoaAsyncSocket是谷歌的开发者,基于BSD-Socket写的一个IM框架,它给Mac和iOS提供了易于使用的、强大的异步套接字库,向上封装出简单易用OC接口。省去了我们面向Socket以及数据流Stream等繁琐复杂的编程。

5、使用CocoaAsyncSocket

首先点击上面的链接下载CocoaAsyncSocket的源码,把以下文件拷贝到自己的项目中:


CocoaAsyncSocket开发使用的文件

我们这里只是简单讲解GCDAsyncSocket的使用,它主要用于开发TCP的连接。由于TCP是长连接,我们需要在自己的项目中使GCDAsyncSocket保持全局唯一性,所以我们在项目里声明一个单例类 AsyncSocketManager以下是AsyncSocketManager.h的结构

@interface AsyncSocketManager : NSObject<GCDAsyncSocketDelegate>
+(AsyncSocketManager *)shareAsyncSocket;


@property (nonatomic,strong) GCDAsyncSocket *asyncSocket;
@property (nonatomic,copy) NSString *socketHost;//注意是ip地址,并不是DNS域名
@property (nonatomic,assign) UInt16 socketPort;
@property (nonatomic,strong) NSTimer *connectTimer;

-(void)socketConnectHost;//连接socket
-(void)cutoffSocket;//断开socket


@end
5.1 Socket的初始化连接
-(void)socketConnectHost{
    //创建socket并指定代理对象为self,代理队列必须为主队列
    self.asyncSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    NSError *error;
    [self.asyncSocket connectToHost:self.socketHost onPort:self.socketPort error:&error];
}

连接成功的代理方法

//连接成功的回调
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    [self addTimer];// 连接成功开启定时器
    [self.asyncSocket readDataWithTimeout:- 1 tag:0];// 连接后,可读取服务端的数据
}

读取数据成功后的代理,连接成功之后需要开启一个定时器规定一定的时间后需要给服务器发送心跳包,用于检测是否服务器在线

// 添加定时器
- (void)addTimer
{
    // 长连接定时器
    self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];
    // 把定时器添加到当前运行循环,并且调为通用模式
    [[NSRunLoop currentRunLoop] addTimer:self.connectTimer forMode:NSRunLoopCommonModes];
}

/** 注意:
    心跳连接中发送给服务端的数据只是作为测试代码,根据你们公司需求,
    或者和后台商定好心跳包的数据以及发送心跳的时间间隔.
    服务端也需要有对应的心跳检测,以此检测客户端是否在线.
 */
-(void)longConnectToSocket{
    NSLog(@"我发送了一次心跳包");
    NSString *longConnect = @"longConnect";//需要和服务器商量好
    NSData *dataStream = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
    
    [self.asyncSocket writeData:dataStream withTimeout:1 tag:1];
}
/**
 读取数据成功的回调
 @param sock 客户端socket
 @param data 读取到的数据
 @param tag 本次读取的标记
 */
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    NSString *text = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"读取的数据==%@",text);
    // 读取到服务端数据值后,能再次读取
    [self.asyncSocket readDataWithTimeout:- 1 tag:0];//这里还需要进行读取操作,否则只能读取一次
}
5.2 断开连接

sokect断开连接时,需要清空代理和客户端本身的socket.

[self.asyncSocket disconnect];//断开连接

/**
 客户端socket断开后的回调
 @param sock 客户端socket
 @param err 错误描述
 */
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    self.asyncSocket.delegate = nil;
    self.asyncSocket = nil;
    [self.connectTimer invalidate];
}
6、总结

CocoaAsyncSocket 是前人帮我们封装好的Socket,如果你想了解的更深的话也可以去了解Apple提供的BSD Socket、CFSocket等接口。

Socket都是用于应用之间进行与服务器之间需要长时间的连接,需要时刻的保持连接,已到达数据时效性。比较常用的就是IM类的应用,不过每一个IM类的应用企业都是自己封装的Socket以适应自己公司的不同业务功能需求。

虽然市面上有非常多的各种各样的Socket框架可以用,但我认为作为一名开发者,我们有责任去搞懂Socket通讯的原理,至少是需要了解。

好了,这篇文章就到这里啦~~~
我最近在逼着自己写文章,以前总是认为像这样的文章网上到处都是而且有一些大神写的非常好,so,我干嘛要写呢……不过最后想想还是认为有必要自己记录下来,别人的永远是别人的,只有自己消化了,理解了,那才能是你自己的东西!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 一.iOS网络编程层次模型 在前文《深入浅出的Cocoa之Bonjour网络编程》中我介绍了如何在Mac系统下进行...
    maTianHong阅读 484评论 1 1
  • 一: 网络各个协议:TCP/IP、SOCKET、HTTP 网络七层由下往上分别为物理层、数据链路层、网络层、传输层...
    iYeso阅读 1,435评论 0 13
  • 在了解socket网络编程之前,我们需要先知道以下几个问题: 网络中进程之间如何通信?Socket是什么?TCP和...
    追风筝的荧火虫阅读 1,257评论 0 17
  • 在了解socket网络编程之前,我们需要先知道以下几个问题: 网络中进程之间如何通信? Socket是什么? TC...
    心至靜行至遠阅读 7,515评论 12 87
  • 城市早已沉睡在甜美的虚伪真实就像刺眼的阳光习惯伸手就档我像火烧在大雨下剩最后微弱的火花看不见国王的新衣裳是否太倔强...
    gxwang阅读 1,888评论 0 0