web开发 php之 socket(TCP/IP)原理 学习、理解和应用

    QQ:337084860

    百度了一些相关知识作为学习和总结,有不对的地方欢迎大家来指正交流

   我们平时浏览网页是这样的 :浏览器输入网址,请求服务器,服务器响应请求返回内容给浏览器,浏览器通过渲染之后就是我们看到的漂亮的网页内容.

    做为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详解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章