现在我们把第一个例子进行完善。你需要监听一个指定的socket并且处理用户的连接。
<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
// Accept any incoming connections to the server
$connection = socket_accept($socket);
if($connection)
{
socket_write($connection, "You have connected to the socket...\n\r");
}
?>
你应该使用你的命令提示符来运行这个例子。理由是因为这里将产生一个服务器,而不是一个Web页面。如果你尝试使用Web浏览器来运行这个脚本,那么很有可能它会超过30秒的限时。你可以使用下面的代码来设置一个无限的运行时间,但是还是建议使用命令提示符来运行。
set_time_limit(0);
在你的命令提示符中对这个脚本进行简单测试:
Php.exe example01_server.php
如果你没有在系统的环境变量中设置php解释器的路径,那么你将需要给php.exe指定详细的路径。当你运行这个服务器端的时候,你能够通过远程登陆(telnet)的方式连接到端口1337来测试这个服务器。如下图:
上面的服务器端有三个问题:1. 它不能接受多个连接。2. 它只完成唯一的一个命令。3. 你不能通过Web浏览器连接这个服务器。
这个第一个问题比较容易解决,你可以使用一个应用程序去每次都连接到服务器。但是后面的问题是你需要使用一个Web页面去连接这个服务器,这个比较困难。你可以让你的服务器接受连接,然后些数据到客户端(如果它一定要写的话),关闭连接并且等待下一个连接。
在上一个代码的基础上再改进,产生下面的代码来做你的新服务器端:
<?php
// Set up our socket
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
// Initialize the buffer
$buffer = "NO DATA";
while(true)
{
// Accept any connections coming in on this socket
$connection = socket_accept($socket);
printf("Socket connected\r\n");
// Check to see if there is anything in the buffer
if($buffer != "")
{
printf("Something is in the buffer...sending data...\r\n");
socket_write($connection, $buffer . "\r\n");
printf("Wrote to socket\r\n");
}
else
{
printf("No Data in the buffer\r\n");
}
// Get the input
while($data = socket_read($connection, 1024, PHP_NORMAL_READ))
{
$buffer = $data;
socket_write($connection, "Information Received\r\n");
printf("Buffer: " . $buffer . "\r\n");
}
socket_close($connection);
printf("Closed the socket\r\n\r\n");
}
?>
这个服务器端要做什么呢?它初始化一个socket并且打开一个缓存收发数据。它等待连接,一旦产生一个连接,它将打印“Socket connected”在服务器端的屏幕上。这个服务器检查缓冲区,如果缓冲区里有数据,它将把数据发送到连接过来的计算机。然后它发送这个数据的接受信息,一旦它接受了信息,就把信息保存到数据里,并且让连接的计算机知道这些信息,最后关闭连接。当连接关闭后,服务器又开始处理下一次连接。(翻译的烂,附上原文)
This is what the server does. It initializes the socket and the buffer that you use to receive
and send data. Then it waits for a connection. Once a connection is created it prints
“Socket connected” to the screen the server is running on. The server then checks to see if
there is anything in the buffer; if there is, it sends the data to the connected computer.
After it sends the data it waits to receive information. Once it receives information it stores
it in the data, lets the connected computer know that it has received the information, and
then closes the connection. After the connection is closed, the server starts the whole
process again.
◆ 产生一个客户端
处理第二个问题是很容易的。你需要产生一个php页连接一个socket,发送一些数据进它的缓存并处理它。然后你又个处理后的数据在还顿,你能够发送你的数据到服务器。在另外一台客户端连接,它将处理那些数据。
To solve the second problem is very easy. You need to create a PHP page that connects to
a socket, receive any data that is in the buffer, and process it. After you have processed the
data in the buffer you can send your data to the server. When another client connects, it
will process the data you sent and the client will send more data back to the server.
下面的例子示范了使用socket:
<?php
// Create the socket and connect
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket,’localhost’, 1337);
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))
{
if($buffer == “NO DATA”)
{
echo(“<p>NO DATA</p>”);
break;
}
else
{
// Do something with the data in the buffer
echo(“<p>Buffer Data: “ . $buffer . “</p>”);
}
}
echo(“<p>Writing to Socket</p>”);
// Write some test data to our socket
if(!socket_write($socket, “SOME DATA\r\n”))
{
echo(“<p>Write failed</p>”);
}
// Read any response from the socket
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))
{
echo(“<p>Data sent was: SOME DATA<br> Response was:” . $buffer . “</p>”);
}
echo(“<p>Done Reading from Socket</p>”);
?>
这个例子的代码演示了客户端连接到服务器。客户端读取数据。如果这是第一时间到达这个循环的首次连接,这个服务器将发送“NO DATA”返回给客户端。如果情况发生了,这个客户端在连接之上。客户端发送它的数据到服务器,数据发送给服务器,客户端等待响应。一旦接受到响应,那么它将把响应写到屏幕上。