上一篇是介绍socket编程的。这次我们实现一个简单的基于socket的消息收发服务。实现思路:先说服务端:接受客户端的连接,读取客户端发送的信息,并将接收到的信息发送给客户端客户端:先连接服务端,读取用户输入,发送信息用户向服务器输入后,服务器会接收到返回的信息。因为PHP本身没有接收用户命令行输入的函数,所以它是通过以下方式实现的:'/dev/stdin',这是linux的标准输入。其实这个函数就是将linux的标准输入重定向到我们后台的PHP程序中。然后我们的PHP程序接收到用户的输入,然后就可以把这个输入发送给echo服务程序的服务器。通过上面的文章,我们已经对创建socket的过程有了一定的了解,这里就不多说了。接下来开始服务器的实现:echo_server.php:代码解读:第1部分:这里直接使用了上一篇介绍的stream_socket_server函数,可以一次性完成socket的创建、绑定和监听。第二部分:开始监听我们创建的socket(至于这里为什么加@,是因为stream_socket_accept函数在一定时间内没有收到客户端的连接就会报警告)第三部分:通过freadfunction,readInputbuffer,一次读取1024字节No.4:将读取到的字符写入inputbuffer,发送给client。通过上面的程序,我们实现了服务器端的回显服务程序。接下来我们就可以运行了,我们会发现我们的echo_server.php已经进入了阻塞状态,等待客户端连接。然后实现客户端:echo_client.php代码解读:第一处:调用我们的重定向标准输入函数,调用这个函数后,如果不输入任何字符,程序不会执行到下一行,因为这里会被阻塞.第二处:如果我们输入字符q,就会跳出while循环,然后执行fclose关闭连接。这里需要注意的是,客户端关闭连接后,会向服务器发送一个信号,告诉服务器我已经断开连接,服务器收到后会关闭这个客户端的连接。第三步:将读取到的输入信息写入缓冲区,发送给服务器。第4至5节是要解释的重点。这里为什么不直接通过fread函数一次性读取服务器返回的消息呢?下面是这个问题的答案:对于每个套接字,都有一个发送缓冲区和一个接收缓冲区。如果我们发送的数据足够大,可能会分两次发送。也就是说,在fwrite之后,我们发送的字符可能会分成两部分发送,而服务端的代码在不停的接收数据,然后返回数据。所以客户端可能会出现以下情况:发送一个字符后,客户端在接收到所有数据之前调用了fread函数,从而打印了多次。所以解决这个问题最好的办法就是我们的客户端可以提前知道要接收的字符的大小,所以这里我们使用strlen函数来获取要接收的数据的大小,如果小于这个大小,继续读取,直到满足条件再输出。下面是程序运行的效果:以上是我们的echo服务程序,记得自己动手练习,亲过一遍,胜过看千遍!我会继续分享一些关于编程和编程自学的文章,记录自己的自学编程。同时也希望我的分享能够对一些对编程感兴趣,正在编程路上的朋友有所帮助。欢迎大家关注我的公众号《阿毛的编码之路》。
