使用GCDAsyncSocket过程中对Socket的总结

一,前言

前段时间一直在开发并维护一个关于收银系统的项目,其中使用了CocoaAsyncSocket.framework这一类库,着重使用的是该类库里面的GCDAsyncSocket类。这里做个梳理。

该类是socket套接字的封装,可用与iOS平台的socket开发。第一次接触socket要始于大学时候了,也仅了解这么一个东西(那什么,出来混总是要还的)......

  • Socket底层是纯C语言,跨平台使用,Socket网络编程在任意一门语言中都很重要,熟悉这些底层交互是提高编程能力的重要一部分。

二,认识Socket

要了解Socket,有些东西想必是绕不过去的...... 0_0

2.1,socket所在的位置

在七层网络模型中的位置:socket是连接应用层与传输层之间的桥梁
著名的网络七层从下往上依次是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。


七层网络模型

2.2,概念

  • http协议 对应于应用层
  • tcp协议 对应于传输层
  • ip协议 对应于网络层

TCP/IP是传输层协议,主要解决数据如何在网络中传输;
HTTP是应用层协议,主要解决如何包装数据;

其实我们在传输数据的时候,可以只使用传输层,数据同样能到达接收方,但是那样的话由于没有应用层,便无法识别数据内容,那传输的数据就没有意义了,要使传输有意义,则就必须使用应用层协议。

应用层协议很多,有HTTP、FTP、TELNET、等等,或者自己定义应用层协议。WEB使用HTTP作为传输层协议,用来封装HTTP文本信息,然后使用TCP/IP做传输协议将它发送到网络上。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket我们可以使用TCP/IP协议。

2.3,HTTP协议

HTTP协议就是超文本传输协议,属于应用层面向对象的协议,常基于TCP连接方式,建立在TCP协议上的一种应用,是web联网的基础,也是手机应用终端常用的协议。

HTTP连接最显著的特点是客户端发送的每次请求都需要服务器返回响应,在请求结束之后,会主动释放连接,俗称“短连接”,从建立连接到关闭连接的过程称为“一次连接”。

由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的 做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客 户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

2.4,TCP协议

TCP协议是传输控制协议,提供面向连接,可靠地字节流服务,提供超时重发,丢弃重复数据,检验数据,流量控制等功能。在正式收发数据前,必须建立可靠的连接,即“三次握手”。

三次握手:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ackj+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

四次挥手:
第一次挥手:数据传输结束以后,客户端的应用进程发出连接释放报文段,并停止发送数据,其首部:FIN=1,seq=u。
第二次挥手:服务器端收到连接释放报文段之后,发出确认报文,其首部:ack=u+1,seq=v。此时本次连接就进入了半关闭状态,客户端不再向服务器发送数据。而服务器端仍会继续发送。
第三次挥手:若服务器已经没有要向客户端发送的数据,其应用进程就通知服务器释放TCP连接。这个阶段服务器所发出的最后一个报文的首部应为:FIN=1,ACK=1,seq=w,ack=u+1。
第四次挥手:客户端收到连接释放报文段之后,必须发出确认:ACK=1,seq=u+1,ack=w+1。 再经过2MSL(最长报文端寿命)后,本次TCP连接真正结束,通信双方完成了他们的告别。
在这个过程中,通信双方的状态如下图,其中:ESTAB-LISHED:连接建立状态、FIN-WAIT-1:终止等待1状态、FIN-WAIT-2:终止等待2状态、CLOSE-WAIT:关闭等待状态、LAST-ACK:最后确认状态、TIME-WAIT:时间等待状态、CLOSED:关闭状态

2.5,UDP协议

用户数据报协议,面向非连接,不保证可靠性的数据传输服务,没有超时重发等机制,故而传输速度很快。

  • 特点:它不与对方建立连接,而是直接的把数据包发送过去,UDP适用于一次只传送少量数据、可靠性要求不高的应用环境。

三,Socket的原理

3.1,Socket概念

Socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。包含进行网络通信的必须的五种信息:双方连接使用的协议、本地主机IP地址,本地进程的协议端口、远地主机的IP地址、远地进程的协议端口。

3.2,建立一个socket连接

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

  • 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
  • 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
  • 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

3.3,Socket与TCP连接的关系

创建Socket连接时候,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP、UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

3.4,Socket连接与HTTP连接关系

通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。
但在实际网络应用 中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。

而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;
若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以 保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

四,Socket使用

首先,根据项目实际需求,这里定义主机(也就是server)是iPad,子机(也就是client)是iPad,iPhone,Android终端等;同时,当设备是iPad时,可以切换主子机角色。

1,基于TCP,GCDAsyncSocket

Server端:

  • 比如在登录成功之后,初始化、设置代理、准备开启连接服务:

server->serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:server delegateQueue:[server serverQueue]];   //初始化、设置代理
BOOL isAccept = [serverSocket acceptOnPort:kPort error:nil];//监测端口

... 表示其他处理的其他操作,

  • 收到连接之后便会走代理

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket{

...
    [clientSocketArray addObject:model];//使用一个数组保存连接的socket,保证此链接是长连接,如果不保存,则连接完会自动断开,从而导致无法互相发送消息
    
...
    TRMessageModel *msg = [[TRMessageModel alloc] init];
    msg.protocol    = TRInnerProtocolOfWelcome;
    msg.queueType   = TRQueueTypeOfSenderLinear;
    msg.data        = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
    msg.isSuccess   = YES;
    msg.hashCode    = msg.hash;
    ...

    [self sendMessageWithSocket:newSocket messageModel:msg];// 发送一些业务信息,其实就是调用[socket writeData:contentData withTimeout:-1 tag:0];方法,根据不同业务发送不同消息

    
    [sock readDataWithTimeout:-1 tag:0];
}

接下来根据不同状态,会走不同的代理方法:

  • 连接之后

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    [sock readDataWithTimeout:-1 tag:0];
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    [sock readDataWithTimeout:-1 tag:tag];
}

  • 发送完数据之后触发代理方法:

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{

}
  • 收到数据之后触发代理方法:

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    LSLog(@"%s",__func__);
    
    ...
      [self receiveMessageWithData:data socketModel:client];// 业务逻辑处理
    ...    
    [sock readDataWithTimeout:-1 tag:tag];
}
  • 客户端断开连接之后

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    //断开之后需要的一些操作
...
// [self detectionHeartbeat];
}

client端:


client.socketModel.socket = [[GCDAsyncSocket alloc] initWithDelegate:client delegateQueue:[client clientQueue]];

与主机端一样,都分别走不同的代理方法

  • 连接之后

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {

    TRMessageModel *msgModel  = [[TRMessageModel alloc] init];
    msgModel.protocol           = TRInnerProtocolOfVerification;
    msgModel.data               = [@"connect" dataUsingEncoding:NSUTF8StringEncoding];
    msgModel.queueType          = TRQueueTypeOfSenderLinear;
    msgModel.deviceCode         = self.deviceCode;
    msgModel.deviceName         = self.deviceName;
    msgModel.isSuccess            = YES;
    msgModel.hashCode           = msgModel.hash;
...    

    [self sendMessageWithSocket:sock messageModel:msgModel];
    self.timestamp = TimeStamp();
    ...    
    [self postSynergismHeartbeat];// 发送心跳包
    [self detectionHeartbeat];// 监测心跳
    
    [sock readDataWithTimeout:-1 tag:0];
}

2,基于UDP,GCDAsyncUDPSocket

GCDAsyncUDPSocket类是iOS下支持UDP协议的socket编程类,使用也很容易,通信的收发过程都有代理可以调用。

五,遇到的一些问题

本项目中使用socket过程中还涉及到一些处理粘包问题、消息等待处理、线程问题、队列、消息广播,设备辨认、心跳、网络环境强弱,数据效率,数据安全,数据格式,跨平台,等等;

有的是业务上的,有的是客观环境下的,有的是技术上的,可见一个稳定的项目要客服很多技术问题,所以程序猿们都很棒有木有。

这些问题这里先不一一写过,在后续总结里面一一探讨

希望各路大佬不吝赐教,指出不足。拍砖!拍砖!拍砖!

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

推荐阅读更多精彩内容

  • OSI七层模型 我们一般使用的网络数据传输由下而上共有七层,分别为物理层、数据链路层、网络层、传输层、会话层、表示...
    泥孩儿0107阅读 803评论 0 2
  • 参考:http://www.2cto.com/net/201611/569006.html TCP HTTP UD...
    F麦子阅读 2,945评论 0 14
  • 第一部分、概念的理解1、什么是Socket?Socket又称之为“套接字”,是系统提供的用于网络通信的方法。它的实...
    Hevin_Chen阅读 2,444评论 0 5
  • 一: 网络各个协议:TCP/IP、SOCKET、HTTP 网络七层由下往上分别为物理层、数据链路层、网络层、传输层...
    iYeso阅读 1,431评论 0 13
  • 展鹏教育目前有四大支柱项目:展鹏作文,佳一数学,远方文学,最美中国字。其中展鹏作文是第一个项目,也是我倾注心血最多...
    大邢老师阅读 478评论 0 1