一次完整的( 二 )


长连接
流程:连接 -> 传输数据 -> 保持连接 -> 传输数据 ->。。。-> 关闭连接 。
长连接指建立SOCKET连接后不管是否使用都保持连接 。但安全性较差 。
http的长连接
HTTP也可以建立长连接的 。使用Connection:keep-alive 。HTTP 1.1默认进行长连接 。
HTTP1.1 和 HTTP1.0 相比较而言 。最大的区别就是增加了长连接支持(貌似最新的 http1.0 可以显示的指定 keep-alive) 。但还是无状态的 。或者说是不可以信任的 。
什么时候用长连接 。短连接?
【一次完整的】长连接多用于操作频繁 。点对点的通讯 。而且连接数不能太多情况 。
每个TCP连接都需要三步握手 。这需要时间 。如果每个操作都是先连接 。再操作的话那么处理速度会降低很多 。
所以每个操作完后都不断开 。次处理时直接发送数据包就OK了 。不用建立TCP连接 。
例如:数据库的连接用长连接 。如果用短连接频繁的通信会造成socket错误 。而且频繁的socket 创建也是对资源的浪费 。
而像WEB网站的http服务一般都用短链接 。因为长连接对于服务端来说会耗费一定的资源 。
而像WEB网站成千上万甚至上亿客户端的频繁连接 。用短连接会更省一些资源 。如果用长连接 。而且同时有成千上万的用户 。如果每个用户都占用一个连接的话 。那可想而知吧 。
所以并发量大 。但每个用户无需频繁操作情况下需用短连好 。
总之 。长连接和短连接的选择要视情况而定 。
数据发送接收方式
异步
报文发送和接收是分开的 。相互独立的 。互不影响 。这种方式又分两种情况:
异步双工:接收和发送在同一个程序中 。由两个不同的子进程分别负责发送和接收
异步单工:接收和发送是用两个不同的程序来完成 。
同步
报文发送和接收是同步进行 。既报文发送后等待接收返回报文 。
同步方式一般需要考虑超时问题 。即报文发出去后不能无限等待 。需要设定超时时间 。超过该时间发送方不再等待读返回报文 。直接通知超时返回 。
在长连接中一般是没有条件能够判断读写什么时候结束 。所以必须要加长度报文头 。读函数先是读取报文头的长度 。再根据这个长度去读相应长度的报文 。
Socket是什么
Socket是应用层与TCP/IP协议族通信的中间软件抽象层 。它是一组接口(TCP/IP是协议 。Socket是他们的具体实现和对外api) 。
在设计模式中 。Socket其实就是一个门面模式 。它把复杂的TCP/IP协议族隐藏在Socket接口后面 。
对用户来说 。一组简单的接口就是全部 。让Socket去组织数据 。以符合指定的协议 。

一次完整的

文章插图
Socket 通信示例
一次完整的

文章插图
主机 A 的应用程序要能和主机 B 的应用程序通信 。必须通过 Socket 建立连接 。而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接 。
建立 TCP 连接需要底层 IP 协议来寻址网络中的主机 。
我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机 。但是一台主机上可能运行着多个应用程序 。如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定 。
这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了 。
建立通信链路(有点烧脑 。可绕过)
当客户端要与服务端通信 。客户端首先要创建一个 Socket 实例 。操作系统将为这个 Socket 实例分配一个没有被使用的本地端口号 。并创建一个包含本地和远程地址和端口号的套接字数据结构 。
这个数据结构将一直保存在系统中直到这个连接关闭 。在创建 Socket 实例的构造函数正确返回之前 。将要进行 TCP 的三次握手协议 。TCP 握手协议完成后 。Socket 实例对象将创建完成 。否则将抛出 IOException 错误 。
与之对应的服务端将创建一个 ServerSocket 实例 。ServerSocket 创建比较简单只要指定的端口号没有被占用 。一般实例创建都会成功 。同时操作系统也会为 ServerSocket 实例创建一个底层数据结构 。这个数据结构中包含指定监听的端口号和包含监听地址的通配符 。通常情况下都是“*”即监听所有地址 。
之后当调用 accept() 方法时 。将进入阻塞状态 。等待客户端的请求 。当一个新的请求到来时 。将为这个连接创建一个新的套接字数据结构 。该套接字数据的信息包含的地址和端口信息正是请求源地址和端口 。

推荐阅读