关于http长连接短连接&tcp连接&socket连接&unix domain socket通信

一,http连接

http协议是 请求/应答 模型。客户端发送请求,服务端对请求做一次响应。服务端只能在客户端发送请求后做一次响应,不能主动发送消息给客户端。

http是应用层协议,传输层用的一般是tcp协议,理论上http应用层协议也可以在传输层采用udp协议,但是如果http协议无状态特点加上udp的不可靠连接,会产生非常糟糕的组合,所以http协议在传输层默认采用tcp协议。

http 1.0短连接

http 1.0默认采用的是短连接,每次交互过程都是如下四个步骤:

  • 客户端和服务端建立tcp连接 (三次握手)
  • 客户端发送数据给服务端
  • 服务端回送响应给客户端
  • 客户端和服务端的tcp连接断开 (四次挥手)

http 1.1长连接

http 1.1默认采用的是长连接。如果客户端和服务端采用http1.1协议进行交互,则默认采用的是长连接,具体表现为客户端的请求header和服务端的响应header里面都有connection :keep-alive 这个标记:

Connection: keep-alive

长连接的优点:

  • 可以在一个tcp连接中处理多个请求。处理多个请求的表现形式有两种:
    • 1,前一个请求/响应结束后,建立的tcp连接并不关闭,而是可以继续用来处理下一个请求/响应,以达到tcp连接的复用。
    • 2,流水线技术(http pipelinning), 即前一个请求发出,还没收到响应时,可以继续发送另外一个请求。不过服务端回送的两次响应顺序必须要跟请求的顺序一致,即遵循FIFO规则。其实资料显示流水线技术使用并不广泛。

结论

http长连接是说tcp连接在一次请求/响应完成后不断开。

2,socket连接

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

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

3,socket连接和tcp连接的关系

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

socket是对TCP/IP协议的封装和应用(程序员层面上),它提供了一组基本的函数接口(比如:create、listen、accept等),使得程序员更方便地使用TCP/IP协议栈。

4,Socket连接和Http连接的关系

Socket连接一般情况下都是TCP连接,因此Socket连接一旦建立,通信双方就可以进行互相发送内容。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态(这也就是常说的“心跳策略”)。关于心跳后面会专门写一篇总结文章。

Http连接是请求/响应的模式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

如果建立的是Socket连接,服务器可以直接将数据传送给客户端;如果方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端。

所以真正的服务端push推送机制,一般是用socket来实现,而不是http长连接来实现。

http 长连接和tcp长连接的关系

Http长连接 和 TCP长连接的区别在于: TCP 的长连接需要自己去维护一套心跳策略。,而Http只需要在请求头加入keep-alive:true即可实现长连接。

internet socket和unix domain socket的关系

上面说的socket连接都是指internet socket连接,是对tcp or udp连接做了一层封装,需要走网卡的。

还有一种socket通信是unix domain socket,比较常见的就是用于同一台主机之间不同进程间通信,比如运行在同一台主机上的nginx和php-fm。

location ~ [^/]\.php(/|$) {
    #fastcgi_pass 127.0.0.1:9000;
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
}

/dev/shm/目录其实是在内存中,这样nginx和php-fpm的交互性能会更高,但是流量很大时会占用很多内存。如果对这个性能追求不是特别高,也可以指定普通目录下的sock文件(硬盘上)。但是不管是/dev/shm/这种内存中的sock文件,还是硬盘上的普通文件,在高负载的情况下都比fastcgi_pass 127.0.0.1:9000这种走tcp连接的性能更好。

参考

1,长连接和短连接
2,什么是长连接
3,HTTP 是基于 TCP 还是 UDP 的
4,nginx 和 php-fpm 通信使用unix socket