十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
OSI 的七层协议体系结构的概念清晰,理论完整,当时它既复杂又不实用; TCP/IP 体系结构则不同,但是它现在却得到了非常广泛的应用,不过从实质上讲, TCP/IP 只是最上面的三层,因为最下面的网络接口层并没有什么具体内容;因此在学习计算机网络的时候往往采取折中的方法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构;
创新互联建站专业为企业提供都江堰网站建设、都江堰做网站、都江堰网站设计、都江堰网站制作等企业网站建设、网页设计与制作、都江堰企业网站模板建站服务,十年都江堰做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
iOS 开发中的网络通信主要是在传输层和应用层进行一些网络 IP 地址,端口以及协议的一些处理;首先是网络层的两种传输协议 UDP 和 TCP 的含义以及区别:
用户数据包协议;UDP 在传输数据之前不需要先建立连接.远地主机的运输层在收到 UDP 报文后,不需要给出任何确认;
主要特点:
传输控制协议; TCP 提供面向连接的服务;在传输数据之前必须先建立连接,数据传输完成后要释放连接;建立连接需要通过三次握手,而释放连接需要四次握手;
主要特点:
第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
这个问题的本质就是信道不可靠,但是通信双方需要中间传输的数据是可靠的,而要解决这个问题,无论你是在信息中包含什么信息,三次通信是理论上的最小值,所以三次握手不是TCP本身的要求,而是为了满足在不可靠信道上可靠的传输信息这一需求所致的;这里的本质需求就是,信道不可靠,数据传输要可靠,三次握手之后你先继续握手还是发数据也好,跟进行可靠信息传输的需求就没关系了,因此如果信道可靠,无论什么时候发出消息,对方一定能收到,或者你不关心是否要保证对方收到你的消息,那就能像UDP那样直接发送消息就可以;
1.当主机A确认发送完数据且知道B已经接受完了,想要关闭发送数据接口(当然确认信号还是可以发),就会发FIN给主机B;
2.主机B收到A发送的FIN,表示收到了,就会发送ACK回复;
3.但是这时B可能还在发送数据,没有想要关闭数据口的意思,所以FIN和ACK不是同时发送的,而是等到B数据发送完,才会发送FIN给主机A;
4.A收到B发来的FIN,知道B的数据也发送完了,回复ACK,A等待2MSL以后,没有收到B传来的任何消息,知道B已经收到自己的ACK了,A就关闭链接,B也关闭链接;
在客户端发送最后的ACK回复,但是该ACK可能丢失。服务端如果没有收到ACK,将不断重复发送FIN片段。所以客户端不能立即关闭,它必须确认服务端接收到了该ACK,客户端会在发送出ACK之后进入到TIME_WAIT状态,客户端会设置一个计时器,等待2MSL的时间,如果在该时间内再次收到FIN,那么客户端会重发ACK并再次等待2MSL;所谓2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果知道2MSL,客户端都没有再次收到FIN,那么客户端推断ACK已经成功接收,则结束TCP连接;
HTTP是一种无状态的连接,客户端每次读取web网页时,服务器都会认为这是一次新的会话。但有时候我们需要持久保存一些用户信息,比如登录时的用户名和密码等;而这些信息都是需要Cookie和Session来保存;
这两个的本质区别就是Cookie是保存在客户端的,而Session是保存在服务器上的;
当服务器接收到 cookie 后,会根据 cookie 中的 SessionID 来找到这个客户的 session。如果没有,则会生成一个新的 SessionID 发送给客户端。
HTTP 连接使用的是"请求--响应"的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据;一次请求后立即断开;HTTP 使用的的面向连接的 TCP 作为传输层协议,保证了数据的可靠性;但是 HTTP属于无状态,无连接;虽然使用了 TCP 连接,但通信的双方不需要先建立连接;
socket 连接通常情况下就是 TCP 连接,因此 socket 连接一旦建立,通信双方即可开始互相发送数据内容,直到双方的连接断开;但在实际应用中,客户端和服务器之间的通行防火墙会关闭长时间处于非活跃状态的连接而导致 socket 连接中断,因此需要通过轮询告诉网络该连接处于活跃状态;
连接过程分为三个步骤:服务器监听,客户端请求,连接确认;
服务器监听 :服务器端套接字并不定位具体的客户端套接字,而是处于等待连接状态,实时监测网络状态,等待客户端的连接请求;
客户端的连接请求 :指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字,为此客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端的套接字的地址和端口号,然后就向服务器端套接字提出连接请求;
连接确认 :当服务器端套接字监听到或者说收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接,而服务器端的套接字继续处于监听状态,继续接受其它客户端套接字的连接请求;
HTTP的 URL 的一般形式是: ;主机:端口/路径
HTTP 的默认端口号是:80;
HTTP 有两类报文:
1.请求报文---从客户端向服务器发送的请求报文
2.响应报文---从服务器到客户的回答
特点:所有的请求参数都拼接都 URL 的后面;
缺点:
特点:
1xx 保留.响应保留;
2xx 请求成功接收;
3xx 为完成请求客户端需要进一步细化请求;
4xx 客户端请求错误(参数,方式不正确);
5xx 服务器端有错误;
前言:
本文总结了iOS客户端与服务器进行交互时,采用 RESTful API + Json 的交互方式,针对不 同的数据形式以及不同的解析方法,如有不足之处,欢迎指正。
先了解一下相关的基本概念。
HTTP通信:
即使用HTTP协议进行通信,工作原理是客户端向服务器端发送一条HTTP请求,服务器收到之后先 解析客户端的请求,之后会返回数据给客户端,然后客户端再对这些数据进行解析和处理。HTTP 连接采取的是“请求—响应”方式,即在请求时建立连接通道,当客户端像服务器端发送请求时,服 务器端才能向客户端发送数据。
Socket通信:Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立 socket连接,可为通信双方的数据传输传提供通道。Socket的主要特点有数据丢失率低,使用简 单且易于移植。Socket类似于peer to peer的连接,一方可随时向另一方喊话。
小结:HTTP和Socket都是基于TCP协议的。使用两种通信方式的情况是: 使用HTTP的情况:双方不需要时刻保持连接在线,比如客户端资源的获取、文件上传等。
使用UDP的情况:大部分即时通讯应用(QQ、微信)、聊天室、苹果APNs等。
主要有四种:
数据流
1.从web服务器响应到手机终端的数据 一般打包在一个字节数组中,这个字节数据中包含了不同的 数据类型,客端端采取Java数据流和过虑流的方式从字节数组中取出各种类型的数据。
这种交互方式我在学习iOS之初用过,实际项目中并没有发现哪家公司在用。这种方式了扩展 了iOS平台在访问Web服务器进行交互时的解析数据能力,仅供研究学习。
2.XML Webservice的标准数据格式。 Protocol Buffers
3.Protocol Buffers 是一种轻便高效的结构化数据存储格式,支持跨平台。它很适合做数据存储或 RPC 数据交换格式。比 JSON 最大的优点就是传输的时候数据体积可以压缩很小,传输效率比较 高。本人在这个在项目中没有用到过。
4.JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。毫无疑问,大家最常用。
本文重点会介绍关于Json数据格式 的常用格式。
Json数据格式 的采用,根据业务情况,一般是团队中的共识。技术的迭代更新,到后期基本都会考虑多 个平台的通用性、可移植性和可读性。比如 我们开发团队,有移动端开发(Android、iOS)、前端开发 (H5开发)和后台开发(golang开发)。
关于服务器的开发规范,我们先来了解一下。
服务器开发规范 我们采用的是 RESTful , RESTful 是目前最流流行的 API设计规范,用于web数据接
口的设计。
• 面面向资源(URI),具有解释性;
• 行为(GET / POST / PUT / PATCH / DELETE)与资源(URI)分离,更更加轻量量;
• 数据描述简单,使用用JSON、XML、Protocol Buffers即可全覆盖, 主要使用用JSON;
它的核心原则是定义用少量方法就能操作的命名资源。资源和方法可视为API的 和动词。
• GET :读取(Read)
• POST :新建(Create)
• PUT :更新(Update),通常是全部更更新
• PATCH :更新(Update),通常是部分更更新
• DELETE :删除(Delete)
项目搭建之始,客户端和服务器一般用 Get 和Post的方式来交互,随着业务的演进和技术的规范迭代, 到后期我们都得按规范来。于是 我们采用了上述几种方式来设计服务器接口,相应地,移动端的请求方 式也得与之对应。
至此,不在赘述 RESTful API 的设计规范,可自行百度了解更多。
接口的数据一般都采用JSON格式进行传输,不过,需要注意的是,JSON的值只有六种数据类型:
•Number:整数或浮点数
•String:字符串
•Boolean:true 或 false
•Array:数组包含在方括号 [] 中
•Object:对象包含在大括号 {} 中
•Null:空类型
传输的数据类型不能超过这六种数据类型,不能用Date数据类型,不同的解析库解析方式不同,可能会 导致异常,如果遇到日期的数据,最好的方式就是使用毫秒数表示日期。
本文总结了iOS与服务器的交互方式和数据类型,并总结了在实际项目的简单运用。数据格式的运
用场景远不止上面提到的几种场景,后期会持续完善,如有不足之处,欢迎指出。
一、网络各个协议:TCP/IP、SOCKET、HTTP等
网络七层由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
其中物理层、数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象;
传输层、会话层、表示层和应用层则被称作主机层,是用户所面向和关心的内容。
http协议对应于应用层
tcp协议对应于传输层
ip协议对应于网络层
三者本质上没有可比性。 何况HTTP协议是基于TCP连接的。
TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。
我 们在传输数据时,可以只使用传输层(TCP/IP),但是那样的话,由于没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用应用层 协议,应用层协议很多,有HTTP、FTP、TELNET等等,也可以自己定义应用层协议。WEB使用HTTP作传输层协议,以封装HTTP文本信息,然 后使用TCP/IP做传输层协议将它发送到网络上。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
二、Http和Socket连接区别
相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助。
2.1、TCP连接
要想明白Socket连接,先要明白TCP连接。手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握
手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连
接之前,TCP
连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客
户端交互,最终确定断开)
2.2、HTTP连接
HTTP协议即超文本传送协议(HypertextTransfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
由
于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的
做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客
户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
三、SOCKET原理
3.1、套接字(socket)概念
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
应
用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个
TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应
用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
3.2 、建立socket连接
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连
接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户
端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
3.3、SOCKET连接与TCP连接
创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。
3.4、Socket连接与HTTP连接
由
于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用
中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致
Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很
多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给
客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以
保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
这里我们使用Socket实现一个聊天室的功能,关于服务器这里的就不介绍了
@interfaceViewController (){
NSInputStream *_inputStream;//对应输入流
NSOutputStream *_outputStream;//对应输出流
}
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewConstraint;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *chatMsgs;//聊天消息数组
@end
懒加载这个消息数组
//从主运行循环移除
//1.建立连接
//定义C语言输入输出流
//把C语言的输入输出流转化成OC对象
//设置代理
//把输入输入流添加到主运行循环
//不添加主运行循环 代理有可能不工作
//打开输入输出流
//登录
//发送用户名和密码
//在这里做的时候,只发用户名,密码就不用发送
//如果要登录,发送的数据格式为 "iam:zhangsan";
//如果要发送聊天消息,数据格式为 "msg:did you have dinner";
//登录的指令11NSString *loginStr =@"iam:zhangsan";
//把Str转成NSData
//建立一个缓冲区 可以放1024个字节
//返回实际装的字节数
//把字节数组转化成字符串
//从服务器接收到的数据
//聊天信息
//刷新表格
//发送数据
//发送完数据,清空textField
//数据多,应该往上滚动
}
//监听键盘
//获取窗口的高度
//键盘结束的Frm
//获取键盘结束的y值