我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PHP中如何实现socket服务器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PHP中如何实现socket服务器

这篇文章主要介绍了PHP中如何实现socket服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP中如何实现socket服务器文章都会有所收获,下面我们一起来看看吧。

socket的中文名字叫做套接字,这种东西就是对TCP/IP的“封装”。现实中的网络实际上只有四层而已,从上至下分别是应用层、传输层、网络层、数据链路层。最常用的http协议则是属于应用层的协议,而socket,可以简单粗暴的理解为是传输层的一种东西。如果还是很难理解,那再粗暴地点儿tcp://218.221.11.23:9999,看到没?这就是一个tcp socket。

socket赋予了我们操控传输层和网络层的能力,从而得到更强的性能和更高的效率,socket编程是解决高并发网络服务器的最常用解决和成熟的解决方案。任何一名服务器程序员都应当掌握socket编程相关技能。

在php中,可以操控socket的函数一共有两套,一套是socket_系列的函数,另一套是stream_系列的函数。socket_是php直接将C语言中的socket抄了过来得到的实现,而stream_系则是php使用流的概念将其进行了一层封装。下面用socket_*系函数简单为这一系列文章开个篇。

先来做个最简单socket服务器:

<?php$host = '0.0.0.0';$port = 9999;// 创建一个tcp socket$listen_socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );// 将socket bind到IP:port上socket_bind( $listen_socket, $host, $port );// 开始监听socketsocket_listen( $listen_socket );// 进入while循环,不用担心死循环死机,因为程序将会阻塞在下面的socket_accept()函数上while( true ){  // 此处将会阻塞住,一直到有客户端来连接服务器。阻塞状态的进程是不会占据CPU的  // 所以你不用担心while循环会将机器拖垮,不会的   $connection_socket = socket_accept( $listen_socket );  // 向客户端发送一个helloworld  $msg = "helloworld\r\n";  socket_write( $connection_socket, $msg, strlen( $msg ) );  socket_close( $connection_socket );}socket_close( $listen_socket );

将文件保存为server.php,然后执行php server.php运行起来。客户端我们使用telnet就可以了,打开另外一个终端执行telnet 127.0.0.1 9999按下回车即可。运行结果如下:

PHP中如何实现socket服务器

简单解析一下上述代码来说明一下tcp socket服务器的流程:

  • 首先,根据协议族(或地址族)、套接字类型以及具体的的某个协议来创建一个socket。

  • 第二,将上一步创建好的socket绑定(bind)到一个ip:port上。

  • 第三,开启监听linten。

  • 第四,使服务器代码进入无限循环不退出,当没有客户端连接时,程序阻塞在accept上,有连接进来时才会往下执行,然后再次循环下去,为客户端提供持久服务。

上面这个案例中,有两个很大的缺陷:

  • 一次只可以为一个客户端提供服务,如果正在为第一个客户端发送helloworld期间有第二个客户端来连接,那么第二个客户端就必须要等待片刻才行。

  • 很容易受到攻击,造成拒绝服务。

分析了上述问题后,又联想到了前面说的多进程,那我们可以在accpet到一个请求后就fork一个子进程来处理这个客户端的请求,这样当accept了第二个客户端后再fork一个子进程来处理第二个客户端的请求,这样问题不就解决了吗?OK!撸一把代码演示一下:

<?php$host = '0.0.0.0';$port = 9999;// 创建一个tcp socket$listen_socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );// 将socket bind到IP:port上socket_bind( $listen_socket, $host, $port );// 开始监听socketsocket_listen( $listen_socket );// 进入while循环,不用担心死循环死机,因为程序将会阻塞在下面的socket_accept()函数上while( true ){  // 此处将会阻塞住,一直到有客户端来连接服务器。阻塞状态的进程是不会占据CPU的  // 所以你不用担心while循环会将机器拖垮,不会的   $connection_socket = socket_accept( $listen_socket );  // 当accept了新的客户端连接后,就fork出一个子进程专门处理  $pid = pcntl_fork();  // 在子进程中处理当前连接的请求业务  if( 0 == $pid ){    // 向客户端发送一个helloworld    $msg = "helloworld\r\n";    socket_write( $connection_socket, $msg, strlen( $msg ) );    // 休眠5秒钟,可以用来观察时候可以同时为多个客户端提供服务    echo time().' : a new client'.PHP_EOL;    sleep( 5 );    socket_close( $connection_socket );    exit;  }}socket_close( $listen_socket );

将代码保存为server.php,然后执行php server.php,客户端依然使用telnet 127.0.0.1 9999,只不过这次我们开启两个终端来执行telnet。重点观察当第一个客户端连接上去后,第二个客户端时候也可以连接上去。运行结果如下:

PHP中如何实现socket服务器

通过接受到客户端请求的时间戳可以看到现在服务器可以同时为N个客户端服务的。但是,接着想,如果先后有1万个客户端来请求呢?这个时候服务器会fork出1万个子进程来处理每个客户端连接,这是会死人的。fork本身就是一个很浪费系统资源的系统调用,1W次fork足以让系统崩溃,即便当下系统承受住了1W次fork,那么fork出来的这1W个子进程也够系统内存喝一壶了,最后是好不容易费劲fork出来的子进程在处理完毕当前客户端后又被关闭了,下次请求还要重新fork,这本身就是一种浪费,不符合社会主义主流价值观。如果是有人恶意攻击,那么系统fork的数量还会呈直线上涨一直到系统崩溃。

所以,我们就再次提出增进型解决方案。我们可以预估一下业务量,然后在服务启动的时候就fork出固定数量的子进程,每个子进程处于无限循环中并阻塞在accept上,当有客户端连接挤进来就处理客户请求,当处理完成后仅仅关闭连接但本身并不销毁,而是继续等待下一个客户端的请求。这样,不仅避免了进程反复fork销毁巨大资源浪费,而且通过固定数量的子进程来保护系统不会因无限fork而崩溃。

<?php$host = '0.0.0.0';$port = 9999;// 创建一个tcp socket$listen_socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );// 将socket bind到IP:port上socket_bind( $listen_socket, $host, $port );// 开始监听socketsocket_listen( $listen_socket );// 给主进程换个名字cli_set_process_title( 'phpserver master process' );// 按照数量fork出固定个数子进程for( $i = 1; $i <= 10; $i++ ){  $pid = pcntl_fork();  if( 0 == $pid ){    cli_set_process_title( 'phpserver worker process' );    while( true ){      $conn_socket = socket_accept( $listen_socket );      $msg = "helloworld\r\n";      socket_write( $conn_socket, $msg, strlen( $msg ) );      socket_close( $conn_socket );    }  }}// 主进程不可以退出,代码演示比较粗暴,为了不保证退出直接走while循环,休眠一秒钟// 实际上,主进程真正该做的应该是收集子进程pid,监控各个子进程的状态等等while( true ){  sleep( 1 );}socket_close( $connection_socket );

将文件保存为server.php后php server.php执行,然后再用ps -ef | grep phpserver | grep -v grep来看下服务器进程状态:

PHP中如何实现socket服务器

可以看到master进程存在,除此之外还有10个子进程处于等待服务状态,再同一个时刻可以同时为10个客户端提供服务。我们通过telnet 127.0.0.1 9999来尝试一下,运行结果如下图:

PHP中如何实现socket服务器

关于“PHP中如何实现socket服务器”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“PHP中如何实现socket服务器”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PHP中如何实现socket服务器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

PHP中如何实现socket服务器

这篇文章主要介绍了PHP中如何实现socket服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP中如何实现socket服务器文章都会有所收获,下面我们一起来看看吧。socket的中文名字叫做套接字,这种
2023-07-05

PHP中如何实现WebSocket服务器

在PHP中实现WebSocket服务器可以使用以下步骤:安装PHP WebSocket库,比如Ratchet:composer require cboden/ratchet创建一个PHP文件,用来作为WebSocket服务器的入口文件,比如
PHP中如何实现WebSocket服务器
2024-04-16

PHP如何实现web socket长链接

本文小编为大家详细介绍“PHP如何实现web socket长链接”,内容详细,步骤清晰,细节处理妥当,希望这篇“PHP如何实现web socket长链接”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。函数介绍服务端
2023-07-05

PHP+Socket之如何实现websocket聊天室

这篇文章主要介绍了PHP+Socket之如何实现websocket聊天室的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP+Socket之如何实现websocket聊天室文章都会有所收获,下面我们一起来看看吧
2023-07-05

PHP+Socket如何实现客户端与服务端数据传输

这篇文章主要介绍“PHP+Socket如何实现客户端与服务端数据传输”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP+Socket如何实现客户端与服务端数据传输”文章能帮助大家解决问题。sock
2023-07-05

PHP如何实现HTTP服务器

这篇文章主要介绍“PHP如何实现HTTP服务器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP如何实现HTTP服务器”文章能帮助大家解决问题。PHP并非不能实现HTTP服务,一般来讲,这叫网络编
2023-07-05

在java项目中使用 Socket如何实现模拟一个HTTP服务器

这篇文章给大家介绍在java项目中使用 Socket如何实现模拟一个HTTP服务器,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。HTTP基于TCP协议,协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请
2023-05-31

Java中Socket如何实现Redis客户端

小编给大家分享一下Java中Socket如何实现Redis客户端,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Redis是最常见的缓存服务中间件,在java开发中,一般使用 jedis 来实现。Redis的命令协议:$参数
2023-06-15

如何进行TCP Socket中的linux实现

这篇文章给大家介绍如何进行TCP Socket中的linux实现,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。TCP Server端:#include #include #incl
2023-06-16

在Java项目中使用Socket 如何实现 一个TCP服务端

在Java项目中使用Socket 如何实现 一个TCP服务端?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1 Java Socket简介  所谓socket 通
2023-05-31

Python基于select实现的socket服务器

本文实例讲述了Python基于select实现的socket服务器。分享给大家供大家参考,具体如下: 借鉴了asyncore模块中select.select的使用方法import socket import traceback import
2022-06-04

Python基于socket如何实现TCP/IP客户和服务器通信

这篇文章主要为大家展示了“Python基于socket如何实现TCP/IP客户和服务器通信”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python基于socket如何实现TCP/IP客户和服务
2023-06-15

php如何实现ip代理服务器

这篇文章主要讲解了“php如何实现ip代理服务器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php如何实现ip代理服务器”吧!在今天的互联网领域,使用IP代理服务器已经成为了许多人的一种选
2023-07-05

PHP+Socket中IO多路复用及实现web服务器的方法是什么

本篇内容介绍了“PHP+Socket中IO多路复用及实现web服务器的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php原生so
2023-07-05

如何利用NIO建立Socket服务器

本篇内容介绍了“如何利用NIO建立Socket服务器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!传统的Java 的IO,利用Socket建
2023-06-17

编程热搜

目录