Socket是什么呢?
socket翻译过来就是套接字,属于传输控制层
websocket是基于tcp的新的网络协议,和http协议已于属于应用层,是一种可以让客户端和服务器进行双向实时通信的技术
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP /IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
你会使用它们吗?
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电 话结束此次交谈。 生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待 客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户 端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
服务端
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP );
socket_bind($socket ,'127.0.0.1', 11211 );
socket_listen( $socket ,5);
while( true ){
$con = socket_accept( $socket );
if( $con !==false ){
socket_write($con, 'init', 4 );
while( $str = socket_read( $con,1024 ) ){
echo 'client:'.$str."\n";
$ret = fgets(STDIN);
}
socket_close( $con );
}
}
客户端
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP );
socket_connect( $socket ,'127.0.0.1', 11211 );
while( $t = socket_read( $socket,1024 ) ){
echo 'server:'.$t."\n";
$str = trim(fgets(STDIN));
if( $str ){
socket_write($socket, $str, strlen($str) );
}
}
socket_close( $socket );
注意
socket_read是一种阻塞型的函数,所谓阻塞就是别的事情都不做,只做这一件事。当read的字符串长度不长时,read可能只需要几个微秒的执行时间,当字符串很长,或者read迟迟没有返回值时,程序就会陷在read的位置,不会继续往下执行。
注意:
socket_accept、socket_read、socket_recv默认都会阻塞,但也可以用socket_set_nonblock()、socket_set_block()设置
PHP手册上对socket_read的具体介绍
PHP_BINARY_READ是默认的socket_read模式,对于结束标志没有固定要求,因此客户端只需要发送信息,服务器端的socket_read读到最后一个字符之后就会结束并返回读到的结果。而PHP_NORMAL_READ则必须在\n、\r或者读到的字符串长度达到参变量$length所规定的最大字符长度之后停止,并返回读操作的结果,否则在NORMAL模式下,socket_read会阻塞程序的进行,一直等待到满足停止read的条件出现为止。
因此在NOAMAL_READ模式下面进行的通信很容易会造成失步。除非每条传输的信息都在末尾加上一个"\n"或者"\r"。
只需要在信息末尾加上换行符或者回车符,NORMAL和BINARY是差不多的。
对于这两个程序来说,并不是客户端发送报错,而是服务器端读指令不能成功结束。