有不对的地方欢迎大家来指正交流
我们平时浏览网页是这样的 :浏览器输入网址,请求服务器,服务器响应请求返回内容给浏览器,浏览器通过渲染之后就是我们看到的漂亮的网页内容.
做为web开发者都知道,浏览器和服务器是通过使用HTTP协议完成从客户端请求到服务器响应等一系列运作流程,而HTTP协议是建立在TCP/IP协议族之上的应用层协议。计算机和网络设备通信其实是通过TCP/IP协议族。
SOCKET
就是对TCP/IP的封装。可以理解为就像php中的面向对像中的类是对对象的一种描述差不多。那么了解socket之前先对tcp/ip简单了解。
TCP/IP
百度上是这样解释TCP/IP:
Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准 。TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,用于端到端的通讯。
可能都知道ISO七层模型,其实就是个定义了一套用于计算机或通信系统间互联的标准体系,就是一种通信标准。如下图:
我们可以看到 HTTP属于应用层,TCP属于传输层他能保障网络间数据传输的完整性和准确性,有兴趣的可以自行深入学习。
进程
我们知道大多数操作系统都支持多程序同时运行,可以理解为各个运行的程序就是(进程).
同一主机,不同进程都有一个唯一的进程号(PID)来标识,用于进程之间的通信。网络通讯就不能这样干了,要是用PID来标识网络进程的话,就有可能PID就重复了,那就乱了。就比如你本来要和叫A的通话,结果还有一个叫A的,你先喊一声谁是A,结果第一个A睡着了,第二个A应答你了,于是你就吧你的小秘密告诉第二个A了,这就尴尬了。。
我们知道IP层的ip地址可以唯一标识主机,而TCP层协议和端口号可以唯一标识主机的一个进程,这样就可以利用ip地址+协议+端口号来唯一标识网络中的一个进程。
前面说了SOCKET是对tcp/ip的抽象,因此我们可以用SOCKET来实现网络间进程通信。图如下:
打破砂锅问到底,因此了解SOCKET通信之前,先简单了解一下TCP/ip通信流程.
资源参考:http://www.2cto.com/net/201310/251896.html
tcp/ip网络通信流程图解:
可以看出分为三步:建立连接、传输数据、断开连接
注意:确认方Ack=发起方seq+1,两端配对(这就是其中的套路)
建立连接:
1.客户端发送 SYN包 sep=x 到服务器
2.server 端 收到SYN包后 会向客户端发送 ACK包和SYN包,告诉客户端已经接受到消息
3.客户端接收到 服务端 的ACK+SYN包后再次向服务端发送ACK包,此时完成链接
传输数据:
client发送的包都有相应的seq编号,server收到数据后,会回复ack进行确认,表示数据已经收到
断开连接
1.client发送一个FIN,用来关闭数据传送
2.server收到FIN包后,发送一个ACK给client表示确认
3.server发送一个FIN,关闭两者间的数据传送
4.client收到FIN后发送ACK给server确认,此时断开连接
接下来SOCKET:
其实上面已经把原理知道了,socket就是用来操作TCP的
再次回顾请求流程以浏览网页为例:
1.建立链接后(俗称三次握手) 通过HTTP协议 向server端口发起请求、
2.server接受并确认请求 ,响应内容通过HTTP给client
3.关闭链接(俗称四次握手)
SOCKET通讯流程图:
server端:
步骤上图已经很明确了:
1.创建流式套接字(TCP) //什么是套接字请自行查阅资料
2. 套接字绑定本地地址和server端口
3. 监听连接请求
4.接受一个新连接,最终返回新的套接字
相关函数查询php手册:http://php.net/manual/zh/function.socket-create.php
resource socket_create ( int $domain , int $type , int $protocol ) //创建一个套接字(通讯节点)
bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )// 给套接字绑定名字(为server端绑定IP和端口)
bool socket_listen ( resource $socket [, int $backlog = 0 ] )//监听套接字上的连接(为client向server端口发起连接,俗称三次握手)
resource socket_accept ( resource $socket )//接受套接字上的连接(它接收连接请求并调用一个子连接Socket来处理客户端和服务器间的信息)
string socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] )//从套接字读取最大长度字节数(读取客户端发送数据流)
int socket_write ( resource $socket , string $buffer [, int $length ] ) //写入套接字(数据传送:向client端)
void socket_close ( resource $socket )// 关闭套接字资源 (如果要继续监听的话只需关闭子连接)
客户端:
1.创建流式套接字(TCP)
2. 利用返回的资源与server端建立连接
resource socket_create ( int $domain , int $type , int $protocol ) //创建一个套接字(通讯节点)
bool socket_connect ( resource $socket , string $address [, int $port = 0 ] )//开启一个套接字连接 里头已经有了目的地址和端口
socket_write($socket, "hello socket") //向server发送数据
int socket_write ( resource $socket , string $buffer [, int $length ] )//数据传送 向server端
void socket_close ( resource $socket )// 关闭套接字资源。
关于应用:
SOCKET 是通常应用于网络通讯,现在HTML5的websocket越来越成熟,可以用来在网页与SOCKET通讯就像打电话一样双方都能互相传达信息,
所以可以做一个网络聊天室来玩玩大笑,是不是很神奇大笑
很简单,就这些,前提是要把TCP/IP搞明白
下一篇写应用层协议:HTTP详解