最近总被问到 Socket 问题, 好久没写了, 干脆总结一下吧。
一、HTTP 、TCP/IP 与 Socket
网络七层分别为:
- 物理层
- 数据链路层
- 网络层
- 传输层
- 会话层
- 表示层
- 应用层
其中, 物理层、数据链路层和网络层通常被称作媒体层, 是网络工程师所研究的对象; 传输层、会话层、表示层和应用层则被称作主机层, 是用户所面向和关心的内容。
HTTP 协议对应于应用层, TCP 协议对应于传输层, IP 协议对应于网络层, 三者本质上没有可比性。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 连接最显著的特点是客户端发送的每次请求都需要服务器回送响应, 在请求结束后, 会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
- 在 HTTP1.0中, 客户端的每次请求都要求建立一次单独的连接, 在处理完本次请求后, 就自动释放连接。
- 在 HTTP1.1中则可以在一次连接中处理多个请求, 并且多个请求可以重叠进行, 不需要等待一个请求结束后再发送下一个请求。
由于 HTTP 在每次请求结束后都会主动释放连接, 因此 HTTP 连接是一种“短连接”, 要保持客户端程序的在线状态, 需要不断地向服务器发起连接请求。通常的
做法是即时不需要获得任何数据, 客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求, 服务器在收到该请求后对客户端进行回复, 表明知道客户端“在线”。若服务器长时间无法收到客户端的请求, 则认为客户端“下线”, 若客户端长时间无法收到服务器的回复, 则认为网络已经断开。
三、Socket 原理
3.1、套接字 ( Socket ) 概念
套接字 ( Socket ) 是通信的基石, 是支持 TCP/IP 协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示, 包含进行网络通信必须的五种信息:连接使用的协议, 本地主机的IP地址, 本地进程的协议端口, 远地主机的IP地址, 远地进程的协议端口。
应用层通过传输层进行数据通信时, TCP 会遇到同时为多个应用程序进程提供并发服务的问题。多个 TCP 连接或多个应用程序进程可能需要通过同一个
TCP 协议端口传输数据。为了区别不同的应用程序进程和连接, 许多计算机操作系统为应用程序与 TCP /IP协议交互提供了套接字( Socket )接口。应层可以和传输层通过 Socket 接口, 区分来自不同应用程序进程或网络连接的通信, 实现数据传输的并发服务。
3.2 、建立 Socket 连接
建立 Socket 连接至少需要一对套接字, 其中一个运行于客户端, 称为Client Socket , 另一个运行于服务器端, 称为Server Socket 。
套接字之间的连接过程分为三个步骤:服务器监听, 客户端请求, 连接确认。
- 服务器监听:服务器端套接字并不定位具体的客户端套接字, 而是处于等待连接的状态, 实时监控网络状态, 等待客户端的连接请求。
- 客户端请求:指客户端的套接字提出连接请求, 要连接的目标是服务器端的套接字。为此, 客户端的套接字必须首先描述它要连接的服务器的套接字, 指出服务器端套接字的地址和端口号, 然后就向服务器端套接字提出连接请求。
- 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时, 就响应客户端套接字的请求, 建立一个新的线程, 把服务器端套接字的描述发给客户端, 一旦客户端确认了此描述, 双方就正式建立连接。而服务器端套接字继续处于监听状态, 继续接收其他客户端套接字的连接请求。
3.3、Socket 连接与 TCP 连接
创建 Socket 连接时, 可以指定使用的传输层协议, Socket 可以支持不同的传输层协议 ( TCP 或UDP) , 当使用 TCP 协议进行连接时, 该 Socket 连接就是一个 TCP 连接。
3.4、Socket 连接与 HTTP 连接
由于通常情况下 Socket 连接就是 TCP 连接, 因此 Socket 连接一旦建立, 通信双方即可开始相互发送数据内容, 直到双方连接断开。但在实际网络应用中, 客户端到服务器之间的通信往往需要穿越多个中间节点, 例如路由器、网关、防火墙等, 大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致
Socket 连接断连, 因此需要通过轮询告诉网络, 该连接处于活跃状态。
而 HTTP 连接使用的是“请求—响应”的方式, 不仅在请求时需要先建立连接, 而且需要客户端向服务器发出请求后, 服务器端才能回复数据。
很多情况下, 需要服务器端主动向客户端推送数据, 保持客户端与服务器数据的实时与同步。此时若双方建立的是 Socket 连接, 服务器就可以直接将数据传送给客户端;若双方建立的是 HTTP 连接, 则服务器需要等到客户端发送一次请求后才能将数据传回给客户端, 因此, 客户端定时向服务器端发送连接请求, 不仅可以保持在线, 同时也是在“询问”服务器是否有新的数据, 如果有就将数据传给客户端。
 李二狗 — @Meniny
                李二狗 — @Meniny
             
            
             
            
             
                 
                