HP使用Berkley的socket库来创建它的连接。你可以知道socket只不过是一个数据结构。你使用这个socket数据结构去开始一个客户端和服务器之间的会话。这个服务器是一直在监听准备产生一个新的会话。当一个客户端连接服务器,它就打开服务器正在进行监听的一个端口进行会话。这时,服务器端接受客户端的连接请求,那么就进行一次循环。现在这个客户端就能够发送信息到服务器,服务器也能发送信息给客户端。产生一个Socket,你需要三个变量:一个协议、一个socket类型和一个公共协议类型。产生一个socket有三种协议供选择,继续看下面的内容来获取详细的协议内容。定义一个公共的协议类型是进行连接一个必不可少的元素。下面的表我们看看有那些公共的协议类型。表一:协议名字/常量描述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用户数据报文协议,它是一个无连接,不可靠的传输协议TCP传输控制协议,这是一个使用最多的可靠的公共协议,它能保证数据包能够到达接受者那儿,如果在传输过程中发生错误,那么它将重新发送出错数据包。现在你知道了产生一个socket的三个元素,那么我们就在php中使用socket_create()函数来产生一个socket。这个socket_create()函数需要三个参数:一个协议、一个socket类型、一个公共协议。socket_create()函数运行成功返回一个包含socket的资源类型,如果没有成功则返回false。Resourecesocket_create(intprotocol,intsocketType,intcommonProtocol)现在你产生一个socket,然后呢?php提供了几个操纵socket的函数。你能够绑定socket到一个IP,监听一个socket的通信,接受一个socket;现在我们来看一个例子,了解函数是如何产生、接受和监听一个socket。上面这个例子产生一个你自己的服务器端。例子第一行,$commonProtocol=getprotobyname(“tcp”)使用公共协议名字来获取一个协议类型。在这里使用的是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_bind($socket,‘localhost’,1337)在这里你绑定socket到本地计算机(127.0.0.1)和绑定socket到你的1337端口。然后你就需要监听所有进来的socket连接。socket_listen($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()删除一个已经分配的iovecsocket_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,如果没有指定则默认当前socketsocket_recvmsg()从iovec里接受消息socket_select()多路选择socket_send()这个函数发送数据到已连接的socketsocket_sendmsg()发送消息到socketsocket_sendto()发送消息到指定地址的socketsocket_set_block()在socket里设置为块模式socket_set_nonblock()socket里设置为非块模式socket_set_option()设置socket选项socket_shutdown()这个函数允许你关闭读、写、或者指定的socketsocket_strerror()返回指定错误号的详细错误socket_write()写数据到socket缓存socket_writev()写数据到分散/聚合数组(注:函数介绍删减了部分原文内容,函数详细使用建议参考英文原文,或者参考PHP手册)以上所有的函数都是PHP中关于socket的,使用这些函数,你必须把你的socket打开,如果你没有打开,请编辑你的php.ini文件,去掉下面这行前面的注释:extension=php_sockets.dll如果你无法去掉注释,那么请使用下面的代码来加载扩展库:如果你不知道你的socket是否打开,那么你可以使用phpinfo()函数来确定socket是否打开。你通过查看phpinfo信息了解socket是否打开。如下图:查看phpinfo()关于socket的信息◆ 产生一个服务器现在我们把第一个例子进行完善。你需要监听一个指定的socket并且处理用户的连接。你应该使用你的命令提示符来运行这个例子。理由是因为这里将产生一个服务器,而不是一个Web页面。如果你尝试使用Web浏览器来运行这个脚本,那么很有可能它会超过30秒的限时。你可以使用下面的代码来设置一个无限的运行时间,但是还是建议使用命令提示符来运行。set_time_limit(0)在你的命令提示符中对这个脚本进行简单测试:Php.exeexample01_server.php如果你没有在系统的环境变量中设置php解释器的路径,那么你将需要给php.exe指定详细的路径。当你运行这个服务器端的时候,你能够通过远程登陆(telnet)的方式连接到端口1337来测试这个服务器。如下图:上面的服务器端有三个问题:1.它不能接受多个连接。2.它只完成唯一的一个命令。3.你不能通过Web浏览器连接这个服务器。这个第一个问题比较容易解决,你可以使用一个应用程序去每次都连接到服务器。但是后面的问题是你需要使用一个Web页面去连接这个服务器,这个比较困难。你可以让你的服务器接受连接,然后些数据到客户端(如果它一定要写的话),关闭连接并且等待下一个连接。在上一个代码的基础上再改进,产生下面的代码来做你的新服务器端:这个服务器端要做什么呢?它初始化一个socket并且打开一个缓存收发数据。它等待连接,一旦产生一个连接,它将打印“Socketconnected”在服务器端的屏幕上。这个服务器检查缓冲区,如果缓冲区里有数据,它将把数据发送到连接过来的计算机。然后它发送这个数据的接受信息,一旦它接受了信息,就把信息保存到数据里,并且让连接的计算机知道这些信息,最后关闭连接。当连接关闭后,服务器又开始处理下一次连接。(翻译的烂,附上原文)Thisiswhattheserverdoes.Itinitializesthesocketandthebufferthatyouusetoreceiveandsenddata.Thenitwaitsforaconnection.Onceaconnectioniscreateditprints“Socketconnected”tothescreentheserverisrunningon.Theserverthencheckstoseeifthereisanythinginthebufferifthereis,itsendsthedatatotheconnectedcomputer.Afteritsendsthedataitwaitstoreceiveinformation.Onceitreceivesinformationitstoresitinthedata,letstheconnectedcomputerknowthatithasreceivedtheinformation,andthenclosestheconnection.Aftertheconnectionisclosed,theserverstartsthewholeprocessagain.◆ 产生一个客户端处理第二个问题是很容易的。你需要产生一个php页连接一个socket,发送一些数据进它的缓存并处理它。然后你又个处理后的数据在还顿,你能够发送你的数据到服务器。在另外一台客户端连接,它将处理那些数据。Tosolvethesecondproblemisveryeasy.YouneedtocreateaPHPpagethatconnectstoasocket,receiveanydatathatisinthebuffer,andprocessit.Afteryouhaveprocessedthedatainthebufferyoucansendyourdatatotheserver.Whenanotherclientconnects,itwillprocessthedatayousentandtheclientwillsendmoredatabacktotheserver.下面的例子示范了使用socket:这个例子的代码演示了客户端连接到服务器。客户端读取数据。如果这是第一时间到达这个循环的首次连接,这个服务器将发送“NODATA”返回给客户端。如果情况发生了,这个客户端在连接之上。客户端发送它的数据到服务器,数据发送给服务器,客户端等待响应。一旦接受到响应,那么它将把响应写到屏幕上。
phpsockets使用
本文列举了所有关于PHP语言中使用socket相关服务的一些函数。注意使用如下函数之前,你需要确保你的socket已打开,如果你没有打开,请编辑你的php.ini文件,去掉下面这行前面的注释(分号):
代码如下:
extension=php_sockets.dll
如果你无法去掉注释,那么请使用下面的代码来加载扩展库:
代码如下:
if(!extension_loaded(’sockets’)){
if(strtoupper(substr(PHP_OS,3))==”WIN”){
dl(’php_sockets.dll’)
}else{
dl(’sockets.so’)
}
}
如果你不知道你的socket是否打开,那么你可以使用phpinfo()函数来确定socket是否打开。你通过查看phpinfo信息了解socket是否打开。
php
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中socket的问题:
1.使用composer require workerman/phpsocket.io导入包;
2.客户端连接方式:
3.服务端连接方式(chat.php,最好单独放一个文件,可以直接访问):
注意:这个时候要启动socket端口,进入cmd到chat.php所在的目录下,运行php chat.php,出现如下:
这说明启动成功。接下来,可以查看下3120端口是否真的已经启动,如下:
php要让服务器使用socket要怎么配置
这是socket的服务端的代码,监听的ip地址是192.168.168.121,端口号为8528
请检查以下几点
这个ip是不是代码所在服务器的ip,一般监测内网ip,如127.0.0.1
端口号是否被使用,可以使用cmd命令 netstat -ano|findstr 8528 查找端口号为8528的端口使用情况
如果要给在公网上使用,请使用公网ip,这样可以外网使用
如果代码不报错可以试下telnet下你的端口号,看是否可以使用
如 telnet 127.0.0.1 8528
解决方案
查看你电脑的ip地址,把上面代码里“$address = ’192.168.168.121’”这个ip地址换成“$address = ’127.0.0.1’”或者你电脑的ip地址,再试试。
(ip地址改成127.0.0.1后,这段代码在我电脑上可以使用)
socket服务器的工作方式是这样的,不间断地运行以等待客户端的连接。一旦客户端连接上了,服务器就会将它添加到客户名单中,然后开始等待来自客户端的消息。
下面是完整的源代码:
// Set time limit to indefinite execution
set_time_limit (0)
// Set the ip and port we will listen on
$address = ’localhost’
$port = 10000
$max_clients = 10
// Array that will hold client information
$client = Array()
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0)
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die(’Could not bind to address’)
// Start listening for connections
socket_listen($sock)
echo ”Waiting for connections…\r\n”
// Loop continuously
while (true) {
// Setup clients listen socket for reading
$read[0] = $sock
for ($i = 0$i <$max_clients$i++) {
if (isset($client[$i][’sock’]))
$read[$i + 1] = $client[$i][’sock’]
}
// Set up a blocking call to socket_select()
if (socket_select($read, $write = NULL, $except = NULL, $tv_sec = 5) <1)
continue
/* if a new connection is being made add it to the client array */
if (in_array($sock, $read)) {
for ($i = 0$i <$max_clients$i++) {
if (empty($client[$i][’sock’])) {
$client[$i][’sock’] = socket_accept($sock)
echo ”New client connected $i\r\n”
break
}
elseif ($i == $max_clients – 1)
echo ”Too many clients…\r\n”
}
} // end if in_array
// If a client is trying to write – handle it now
for ($i = 0$i <$max_clients$i++) { // for each client
if (isset($client[$i][’sock’])) {
if (in_array($client[$i][’sock’], $read)) {
$input = socket_read($client[$i][’sock’], 1024)
if ($input == null) {
echo ”Client disconnecting $i\r\n”
// Zero length string meaning disconnected
unset($client[$i])
} else {
echo ”New input received $i\r\n”
// send it to the other clients
for ($j = 0$j <$max_clients$j++) {
if (isset($client[$j][’sock’]) &&$j != $i) {
echo ”Writing ’$input’ to client $j\r\n”
socket_write($client[$j][’sock’], $input, strlen($input))
}
}
if ($input == ’exit’) {
// requested disconnect
socket_close($client[$i][’sock’])
}
}
} else {
echo ”Client disconnected $i\r\n”
// Close the socket
socket_close($client[$i][’sock’])
unset($client[$i])
}
}
}
} // end while
// Close the master sockets
socket_close($sock)
可以先将它分解为几个较小的部分。
第一部分是创建服务器。Lines:2至20。
这部分代码设置了变量、地址、端口、最大客户端和客户端数组。接下来创建socket并将其绑定到我们指定的地址和端口上。
下面我们要做的事情就是执行一个死循环(实际上我们是故意的!)。Lines:22至32。
在这部分代码中我们做的第一步是设置 $read 数组。此数 组包含所有客户端的套接字和我们主服务器的套接字。这个变量稍后会用于select语句:告诉PHP监听来自这些客户端的每一条消息。
socket_select()的最后一个参数告诉我们的服务器在返回值之前最多等待5秒钟。如果它的返回值小于1,那么就表示没有收到任何数据,所以只需要返回循环顶部,继续等待。
脚本的下一个部分,是增加新的客户端到数组中。Lines:33至44。
将新的客户端放置在列表的末尾。检查以确保客户端的数量没有超过我们想要服务器处理的数量。
下面要介绍的代码块相当大,也是服务器的主要部分。当客户端将消息发送到服务器时,就需要这块代码挺身而出来处理。消息可以是各种各样的,断开消息、实际断开——只要是服务器需要处理的消息。Lines:46至末尾。
代码循环通过每个客户端并检查是否收到来自于它们的消息。如果是,获取输入的内容。根据输入来检查这是否是一个断开消息,如果是那就从数组中删除它们,反之,那它就是一个正常的消息,那我们的服务器再次通过所有客户端,并一个一个写信息给他们,跳过发送者。
以上就是关于PHP编程语言中的socket是什么东西全部的内容,如果了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!