2019-01-16 15:07:20  498990 4

php网络编程之socket的常用函数介绍以及简单实用

 标签:   

网络中是如何通信数据传输?


ip+端口+协议

实现网络进程之间的通信,几乎所有的应用程序都是采用socket,“一切皆socket”。


HTTP TCP SOCKET 区别


Http协议:对应于应用层。Http协议是基于TCP链接的。
tcp协议:对应于传输层
ip协议: 对应与网络层

TCP/IP是传输层协议,主要解决数据如何在网络中传输;而Http是应用层协议,主要解决如何包装数据。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

Http连接:http连接就是所谓的短连接,及客户端向服务器发送一次请求,服务器端相应后连接即会断掉。

socket连接:socket连接及时所谓的长连接,理论上客户端和服务端一旦建立连接,则不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该链接已释放网络资源。所以当一个socket连接中没有数据的传输,那么为了位置连续的连接需要发送心跳消息,具体心跳消息格式是开发者自己定义的。

什么是socket?


Socket的英文原义是“孔”或“插座”,通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。


Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

socket2.jpg


socket连接的3个步骤

  (1)服务器监听:ip+端口号

(2)客户端请求:发出向 服务器 的 ip以及端口连接请求

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

socket3.jpg


PHP之socket的安装准备


linux系统

编译PHP时必须在配置中添加--enable-sockets 配置项来启用。

可以使用 lnmp一键安装包:https://github.com/lampol

windows  (不推荐使用,这里不介绍)


socket的简单的demo演示


server.php

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,'0.0.0.0',6666);
socket_listen($socket);
$sock = socket_accept($socket);
$res = socket_read($sock,2048);
echo $res;
socket_write($sock,'hello client’);


client.php

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_connect($socket,'127.0.0.1',6666);
$msg = 'hlllo server';
socket_write($socket,$msg);
$res = socket_read($socket,2048);
echo $res;


首先运行:  php  server.php 


1.jpg

2.jpg


然后 在运行  php  client.php


3.jpg

4.jpg

socket常用函数的介绍


官方文档:http://php.net/manual/zh/book.sockets.php


//创建一个套接字(通讯节点)
resource  socket_create ( int $domain , int $type , int $protocol )  


//获取错误码
$errcode = socket_last_error();   

//获取错误信息  根据错误码
$errmsg = socket_strerror($errcode); 

//绑定套接字资源 地址 以及端口
bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )

socket

    用 socket_create() 创建的一个有效的套接字资源。

address

    如果套接字是 AF_INET 族,那么 address 必须是一个四点分法的 IP 地址(例如 127.0.0.1 )。

如果套接字是 AF_UNIX 族,那么 address 是 Unix 套接字一部分(例如 /tmp/my.sock )

port (可选)

    参数 port 仅仅用于 AF_INET 套接字连接的时候,并且指定连接中需要监听的端口号。


//监听被绑定的socket 地址端口
bool socket_listen ( resource $socket [, int $backlog = 0 ] )


//接受客户端的连接  阻塞的
resource socket_accept ( resource $socket )

//连接指定的套接字资源
bool socket_connect ( resource $socket , string $address [, int $port = 0 ] )

//传数据到套接字
int socket_write ( resource $socket , string $buffer [, int $length = 0 ] )
 
int socket_send ( resource $socket , string $buf , int $len , int $flags ) 

//读取 socket 传过来的数据
string socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] )

//注意:server端的 应该是 accept 返回的资源
int socket_recv ( resource $socket , string &$buf , int $len , int $flags )

  
//关闭套接字 资源
void socket_close ( resource $socket )

//获取连接过来的客户端ip地址和端口 socket  连接过来的套接字资源
socket_getpeername ( resource $socket , string &$address [, int &$port ] ) 

//设置套接字选项
socket_set_option ( resource $socket , int $level , int $optname , mixed $optval )

$socket   socket_create或者socket_accept的函数返回值

$level      这个值 SOL_SOCKET

$optname 
SO_REUSEADDR  是让套接字端口释放后立即就可以被再次使用
SO_RCVTIMEO   是套接字的接收资源的最大超时时间
SO_SNDTIMEO   是套接字的发送资源的最大超时时间

$optval
参数3假如是后两个,则参数4是一个这样的数组array('sec'=>1,'usec'=>500000),如果是第一个 就是true 或者false

//获取套接字选项
socket_get_option ( resource $socket , int $level , int $optname )

//实现io多路复用 返回活跃的连接
socket_select ( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] )

注意 :前三个参数都是引用传值。

$read  服务端监听的套接字资源,当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。

$write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。

$except是$sockets里面要被排除的元素,传入NULL是”监听”全部。

第四个参数为null为阻塞, 为0位非阻塞, 为 >0 为等待时间



返回 活跃的链接数  当有连接 或数据操作时就会返回

//



4 条留言此文章没有人评论

给我留言

评论内容