PHP SOCKET基础内容Word文档下载推荐.docx
《PHP SOCKET基础内容Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《PHP SOCKET基础内容Word文档下载推荐.docx(25页珍藏版)》请在冰豆网上搜索。
表一:
协议
名字/常量描述
AF_INET这是大多数用来产生socket的协议,使用TCP或UDP来传输,用在IPv4的地址
AF_INET6与上面类似,不过是来用在IPv6的地址
AF_UNIX本地协议,使用在Unix和Linux系统上,它很少使用,一般都是当客户端和服务器在同一台及其上的时候使用
表二:
Socket类型
SOCK_STREAM这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。
这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM这个协议是无连接的、固定长度的传输调用。
该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET这个协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。
必须把这个包完整的接受才能进行读取。
SOCK_RAW这个socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。
(ping、traceroute使用该协议)
SOCK_RDM这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
表三:
公共协议
ICMP互联网控制消息协议,主要使用在网关和主机上,用来检查网络状况和报告错误信息
UDP用户数据报文www.ks-协议,它是一个无连接,不可靠的传输协议
TCP传输控制协议,这是一个使用最多的可靠的公共协议,它能保证数据包能够到达接受者那儿,如果在传输过程中发生错误,那么它将重新发送出错数据包。
现在你知道了产生一个socket的三个元素,那么我们就在php中使用socket_create()函数来产生一个socket。
这个socket_create()函数需要三个参数:
一个协议、一个socket类型、一个公共协议
。
socket_create()函数运行成功返回一个包含socket的资源类型,如果没有成功则返回false。
Resourecesocket_create(intprotocol,intsocketType,intcommonProtocol);
现在你产生一个socket,然后呢?
php提供了几个操纵socket的函数。
你能够绑定socket到一个IP,监听一个socket的www.ks-通信,接受一个socket;
现在我们来看一个例子,了解函数是如何产生、接受
和监听一个socket。
<
?
php
$commonProtocol=getprotobyname(“tcp”);
$socket=socket_create(AF_INET,SOCK_STREAM,$commonProtocol);
socket_bind($socket,‘localhost’,1337);
socket_listen($socket);
//Moresocketfunctionalitytocome
>
上面这个例子产生一个你自己的服务器端。
例子第一行,
使用公共协议名字来获取一个协议类型。
在这里使用的是TCP公共协议,如果你想使用UDP或者ICMP协议,那么你应该把getprotobyname()函数的参数改为“udp”或“icmp”。
还有一个可选的办法
是不使用getprotobyname()函数而是指定SOL_TCP或SOL_UDP在socket_create()函数中。
$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
例子的第二行是产生一个socket并且返回一个socket资源的实例。
在你有了一个socket资源的实例以后,你就必须把socket绑定到一个IP地址和某一个端口上。
在这里你绑定socket到本地计算机(127.0.0.1)和绑定socket到你的1337端口。
然后你就需要监听所有进来的socket连接。
在第四行以后,你就需要了解所有的socket函数和他们的使用。
表四:
Socket函数
函数名描述
socket_accept()接受一个Socket连接
socket_bind()把socket绑定在一个IP地址和端口上
socket_clear_error()清除socket的错误或者最后的错误代码
socket_close()关闭一个socket资源
socket_connect()开始一个socket连接
socket_create_listen()在指定端口打开一个socket监听
socket_create_pair()产生一对没有区别的socket到一个数组里
socket_create()产生一个socket,相当于产生一个socket的数据结构
socket_get_option()获取socket选项
socket_getpeername()获取远程类似主机的ip地址
socket_getsockname()获取本地socket的ip地址
socket_iovec_add()添加一个新的向量到一个分散/聚合的数组
socket_iovec_alloc()这个函数创建一个能够发送接收读写的iovec数据结构
socket_iovec_delete()删除一个已经分配的iovec
socket_iovec_fetch()返回指定的iovec资源的数据
socket_iovec_free()释放一个iovec资源
socket_iovec_set()设置iovec的数据新值
socket_last_error()获取当前socket的最后错误代码
socket_listen()监听由指定socket的所有连接
socket_read()读取指定长度的数据
socket_readv()读取从分散/聚合数组过来的数据
socket_recv()从socket里结束数据到缓存
socket_recvfrom()接受数据从指定的socket,如果没有指定则默认当前socket
socket_recvmsg()从iovec里接受消息
socket_select()多路选择
socket_send()这个函数发送数据到已连接的socket
socket_sendmsg()发送消息到socket
socket_sendto()发送消息到指定地址的socket
socket_set_block()在socket里设置为块模式
socket_set_nonblock()socket里设置为非块模式
socket_set_option()设置socket选项
socket_shutdown()这个函数允许你关闭读、写、或者指定的socket
socket_strerror()返回指定错误号的详细错误
socket_write()写数据到socket缓存
socket_writev()写数据到分散/聚合数组
(注:
函数介绍删减了部分原文内容,函数详细使用建议参考英文原文,或者参考PHP手册)
以上所有的函数都是PHP中关于socket的,使用这些函数,你必须把你的socket打开,如果你没有打开,请编辑你的php.ini文件,去掉下面这行前面的注释:
extension=php_sockets.dll
如果你无法去掉注释,那么请使用下面的代码来加载扩展库:
php
if(!
extension_loaded(‘sockets’)){
if(strtoupper(substr(PHP_OS,3))==“WIN”){
dl(‘php_sockets.dll’);
}else{
dl(‘sockets.so’);
}
}
如果你不知道你的socket是否打开,那么你可以使用phpinfo()函数来确定socket是否打开。
你通过查看phpinfo信息了解socket是否打开。
如下图:
查看phpinfo()关于socket的信息
◆ 产生一个服务器
现在我们把第一个例子进行完善。
你需要监听一个指定的socket并且处理用户的连接。
$commonProtocol=getprotobyname("
tcp"
);
socket_bind($socket,'
localhost'
1337);
//Acceptanyincomingconnectionstotheserver
$connection=socket_accept($socket);
if($connection){
socket_write($connection,"
Youhaveconnectedtothesocket...\n\r"
你应该使用你的命令提示符来运行这个例子。
理由是因为这里将产生一个服务器,而不是一个Web页面。
如果你尝试使用Web浏览器来运行这个脚本,那么很有可能它会超过30秒的限时。
你可以使用
下面的代码来设置一个无限的运行时间,但是还是建议使用命令提示符来运行。
set_time_limit(0);
在你的命令提示符中对这个脚本进行简单测试:
Php.exeexample01_server.php
如果你没有在系统的环境变量中设置php解释器的路径,那么你将需要给php.exe指定详细的路径。
当你运行这个服务器端的时候,你能够通过远程登陆(telnet)的方式连接到端口1337来测试这个
上面的服务器端有三个问题:
1.它不能接受多个连接。
2.它只完成唯一的一个命令。
3.你不能通过Web浏览器连接这个服务器。
这个第一个问题比较容易解决,你可以使用一个应用程序去每次都连接到服务器。
但是后面的问题是你需要使用一个Web页面去连接这个服务器,这个比较困难。
你可以让你的服务器接受连接,然
后些数据到客户端(如果它一定要写的话),关闭连接并且等待下一个连接。
在上一个代码的基础上再改进,产生下面的代码来做你的新服务器端:
//Setupoursocket
//Initializethebuffer
$buffer="
NODATA"
;
while(true){
//Acceptanyconnectionscominginonthissocket
$connection=socket_accept($socket);
printf("
Socketconnected\r\n"
//Checktoseeifthereisanythinginthebuffer
if($buffer!
="
"
){
printf("
Somethingisinthebuffer...sendingdata...\r\n"
socket_write($connection,$buffer."
\r\n"
Wrotetosocket\r\n"
NoDatainthebuffer\r\n"
//Gettheinput
while($data=socket_read($connection,1024,PHP_NORMAL_READ)){
$buffer=$data;
socket_write($connection,"
InformationReceived\r\n"
Buffer:
"
.$buffer."
socket_close($connection);
Closedthesocket\r\n\r\n"
这个服务器端要做什么呢?
它初始化一个socket并且打开一个缓存收发数据。
它等待连接,一旦产生一个连接,它将打印“Socketconnected”在服务器端的屏幕上。
这个服务器检查缓冲区,如果
缓冲区里有数据,它将把数据发送到连接过来的计算机。
然后它发送这个数据的接受信息,一旦它接受了信息,就把信息保存到数据里,并且让连接的计算机知道这些信息,最后关闭连接。
当连接
关闭后,服务器又开始处理下一次连接。
(翻译的烂,附上原文)
Thisiswhattheserverdoes.Itinitializesthesocketandthebufferthatyouusetoreceive
andsenddata.Thenitwaitsforaconnection.Onceaconnectioniscreateditprints
“Socketconnected”tothescreentheserverisrunningon.Theserverthencheckstoseeif
thereisanythinginthebuffer;
ifthereis,itsendsthedatatotheconnectedcomputer.
Afteritsendsthedataitwaitstoreceiveinformation.Onceitreceivesinformationitstores
itinthedata,letstheconnectedcomputerknowthatithasreceivedtheinformation,and
thenclosestheconnection.Aftertheconnectionisclosed,theserverstartsthewhole
processagain.
◆ 产生一个客户端
处理第二个问题是很容易的。
你需要产生一个php页连接一个socket,发送一些数据进它的缓存并处理它。
然后你又个处理后的数据在还顿,你能够发送你的数据到服务器。
在另外一台客户端连接
,它将处理那些数据。
Tosolvethesecondproblemisveryeasy.YouneedtocreateaPHPpagethatconnectsto
asocket,receiveanydatathatisinthebuffer,andprocessit.Afteryouhaveprocessedthe
datainthebufferyoucansendyourdatatotheserver.Whenanotherclientconnects,it
willprocessthedatayousentandtheclientwillsendmoredatabacktotheserver.
下面的例子示范了使用socket:
//Createthesocketandconnect
$connection=socket_connect($socket,’localhost’,1337);
while($buffer=socket_read($socket,1024,PHP_NORMAL_READ)){
if($buffer=="
echo("
p>
NODATA<
/p>
break;
//Dosomethingwiththedatainthebuffer
BufferData:
echo("
WritingtoSocket<
//Writesometestdatatooursocket
socket_write($socket,"
SOMEDATA\r\n"
)){
echo("
Writefailed<
//Readanyresponsefromthesocket
Datasentwas:
SOMEDATA<
br>
Responsewas:
DoneReadingfromSocket<
这个例子的代码演示了客户端连接到服务器。
客户端读取数据。
如果这是第一时间到达这个循环的首次连接,这个服务器将发送“NODATA”返回给客户端。
如果情况发生了,这个客户端在连接之
上。
客户端发送它的数据到服务器,数据发送给服务器,客户端等待响应。
一旦接受到响应,那么它将把响应写到屏幕上。
这些Socket函数直接跟互联网的协议进行发送信息。
相对于fopensock的流来讲,他们操作在一个比较底层的级别。
通常,他们都是对C函数进行封装,并且名称都类似。
如果你有使用C进行socket编
程的经验,那么使用这些函数将是非常熟练的。
我们这里不讨论特别详细的socket编程。
使用这些函数能够解决高层级别函数所不能解决的难题。
使用这些函数能够实现类似fopen的功能,你也许有很多方法来实现socket的功能,比如在PHP中使用CLI(Command-lineInterface)来实
现的Internet守护进程。
resourcesocket_accept(resourcesocket)
在你的脚本服务器端中,使用socket_accept接受一个进入的连接。
你必须首先产生一个socket,绑定它到一个名字,并且设置它监听一个端口。
在块模式中,socket_accept将产生一个唯一接受后
的连接。
在非块模式中,它没有建立连接则返回false。
另外,当你有了一个新的socket资源后就能够进行读写操作。
下面我们将示范一个简单的回显服务器端。
它运行在CLI(命令行)下面,它在12345端口等待客户端的连接。
socket_accept
set_time_limit(0);
//createthesocket
if(($socket=socket_create(AF_INET,SOCK_STREAM,0))<
0)
{
print("
Couldn'
tcreatesocket:
.socket_strerror(socket_last_error())."
\n"
//bindittothegivenaddressandport
if(($error=socket_bind($socket,gethostbyname($_SERVER['
HOSTNAME'
]),12345))<
tbindsocket:
if(($error=socket_listen($socket,5))<
tlistonsocket:
.
socket_strerror(socket_last_error())."
while(TRUE)
//waitforconnection
if(($accept=socket_accept($socket))<
Errorwhilereading:
.socket_strerror($message)."
break;
//sendwelcomemessage
socket_write($accept,"
Connectionaccepted\n"
print