“PHP”从一个简单的套接字服务器开始

socket的中文名字叫做套接字,这种东西就是对TCP/IP的“封装”。现实中的网络实际上只有四层而已,从上至下分别是应用层、传输层、网络层、数据链路层。最常用

很多朋友对于“PHP”从一个简单的套接字服务器开始和不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!

在PHP中,有两套函数可以控制socket,一套是socket_系列函数,一套是stream_系列函数。 Socket_是PHP直接用C语言复制socket得到的实现,而stream_系统是PHP利用流的概念进行封装的。下面使用socket_*系列函数来简单开始本系列文章。

我们先来做一个最简单的socket服务器:

?php$主机=’0.0.0.0′;$端口=9999; //创建TCP 套接字$listen_socket=socket_create( AF_INET, SOCK_STREAM, SOL_TCP ); //将socket绑定到IP:端口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 并按Enter。运行结果如下:

“PHP”从一个简单的套接字服务器开始

我们简单分析一下上面的代码来解释一下tcp socket server的流程:

1. 首先,根据协议族(或地址族)、套接字类型和特定协议创建套接字。 2. 其次,将上一步中创建的套接字绑定到ip: 端口。 3. 第三,打开监听。 4、第四,让服务器代码进入死循环而不退出。当没有客户端连接时,程序在接受时阻塞。只有当有连接进来时才会向下执行,然后再次循环为客户端提供持久化服务。上述案例有两个很大的缺陷:

1. 一次只能提供一个客户端。如果在将helloworld 发送到第一个客户端时有第二个客户端连接,则第二个客户端必须等待一段时间。 2、容易受到攻击,造成拒绝服务。分析完上面的问题,我们就想到了前面提到的多进程。然后我们可以在accpet收到请求后fork一个子进程来处理客户端的请求。这样,在接受第二个客户端之后,我们就可以fork一个子进程了。处理第二个客户端的请求,这样不就解决问题了吗?好的!让我们用一些代码来演示:

“PHP”从一个简单的套接字服务器开始

?php$主机=’0.0.0.0′;$端口=9999; //创建TCP 套接字$listen_socket=socket_create( AF_INET, SOCK_STREAM, SOL_TCP ); //将socket绑定到IP:端口socket_bind( $listen_socket, $host, $port );//开始监听socketsocket_listen( $listen_socket );//进入while循环,不用担心死循环崩溃,因为程序会阻塞在下面的socket_accept()函数上while( true ){ //这里它将被阻塞,直到有客户端来连接服务器。被阻塞的进程不会占用CPU //所以你不必担心while循环会导致机器宕机,没有$connection_socket=socket_accept( $listen_socket ); //当接受新的客户端连接时, fork 创建一个专门处理的子进程$pid=pcntl_fork(); //在子流程中处理当前连接的请求业务if( 0==$pid ){ //向客户端发送helloworld $msg=’helloworld\r\ n’; socket_write( $connection_socket, $msg, strlen( $msg ) ); //休眠5秒,可用于同时观察和服务多个客户端echo time().’第:章一个新的客户端’.PHP_EOL;睡眠(5); socket_close( $connection_socket );出口; }}socket_close( $listen_socket );将代码保存为server.php,然后执行php server.php。客户端仍然使用telnet 127.0.0.1 9999,只是这次我们打开两个终端来执行telnet。值得注意的是,第一个客户端连接后,第二个客户端也可以连接。运行结果如下:

通过接收客户端请求的时间戳,可以看到服务器现在可以同时为N个客户端提供服务。但是,再想一想,如果有10000个客户来请求怎么办?这时服务器会fork出10000个子进程来处理每个客户端连接,这会害死人的。 fork本身就是一个系统调用,浪费系统资源。 10,000 个分叉就足以导致系统崩溃。即使系统能承受1000次fork,fork出来的1000个子进程也足够喝掉一盆系统内存了。最后,还好吗?容易fork出的子进程在处理完当前客户端后会被关闭,下次请求时还得再次fork。这本身就是一种浪费,也不符合社会主义主流价值观。如果出现恶意攻击,系统分叉的数量会线性增加,直至系统崩溃。

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

“PHP”从一个简单的套接字服务器开始

?php$主机=’0.0.0.0′;$端口=9999; //创建TCP 套接字$listen_socket=socket_create( AF_INET, SOCK_STREAM, SOL_TCP ); //绑定socket到IP:端口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 工作进程’ ); while( true ){ $conn_socket=socket_accept( $listen_socket ); $msg=’你好世界\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 phpserver | grep phpserver grep -v grep 查看服务器进程状态:

可以看到master进程存在。另外还有10个等待服务的子进程,可以同时为10个客户端提供服务。我们通过telnet 127.0.0.1 9999来尝试一下,结果如下:

好了,PHP新征程系列就从简单的介绍开始吧!下一篇文章将介绍一些更深刻的理论基础。

用户评论

“PHP”从一个简单的套接字服务器开始
浅嫣婉语

想学一学网络编程!这篇文章正好合适。感觉这篇文章讲解得非常明确易懂,尤其对像我这样入门的人来说很有帮助。打算跟着教程一步步做一遍,实践一下!

    有15位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
羁绊你

Socket编程确实挺有意思的,可以自己搭建一个小型的服务器体验一下代码执行的效果。不过对于初学者来说,可能有些地方比较难理解吧,需要多花些时间看文档。建议作者后期可以补充一些详细的解释和例子。

    有12位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
念旧情i

PHP虽然功能强大,但是如果涉及网络编程,还需要掌握一定的底层知识,比如Socket相关的操作。这篇文章刚好介绍了最基本的socket服务器的搭建,希望能帮助我更好地理解php在网络方面的应用。

    有8位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
艺菲

学习Socket程序感觉很有成效! 能自己搭建一个简单的服务器,体会一下数据传输的过程确实很刺激。 现在我已经开始尝试写一些客户端代码来与这个服务器进行交互了!

    有16位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
夏至离别

PHP 做Socket服务器?这听起来有些奇怪吧,感觉 PHP more 适合web开发. 不过既然有人做了,也是可以参考一下学习的! 对底层概念理解加深总没有坏处吧。

    有5位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
几妆痕

这个文章挺实用的,讲解比较透彻,我之前也尝试过用PHP实现Socket服务器搭建,但遇到了一些问题。看了这篇文章,感觉自己离目标又近了一步了!

    有14位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
打个酱油卖个萌

想问下,学习Socket编程,还需要掌握哪些相关的基础知识呢? 比如什么操作系统知识,或是网络协议? 这些对理解Socket编程至关重要吧?

    有18位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
减肥伤身#

作者的代码写的很简洁明了,很容易理解。感觉自己也能跟着做一遍! 希望以后可以学到更多深入的Socket服务器程序设计,比如处理并发连接,安全认证等等

    有12位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
执拗旧人

这篇文章对我来说太入门了,我之前已经接触过 Socket 编程一段时间了,希望能看到一些更高级的使用场景和应用示例。比如如何构建一个安全的聊天服务器或者文件传输服务器?

    有13位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
青衫负雪

我觉得这个文章可以做成系列教程,从简单的Socket服务器开始,逐步讲解更加复杂的网络编程应用场景。这样对入门的人学习起来会更有帮助。

    有15位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
花菲

PHP 确实可以用来搭建 Socket 服务器,而且在处理一些小规模的实时交互应用程序时很实用。不过对于需要高并发、高性能的应用来说,可能还需要考虑其他的语言和方案。

    有9位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
心脏偷懒

我本来想用Java搭建一个Socket服务器,可是看到了这篇文章后觉得PHP也能实现,而且更加简单方便! 准备试试这个方法看看效果怎么样

    有10位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
丢了爱情i

对于我这种只对Web开发感兴趣的人来说, Socket编程确实有些鸡肋的感觉。 但是学习它还是能够让我更深入地了解网络协议和数据传输的机制。

    有15位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
_心抽搐到严重畸形っ°

php写socket服务器? 这真是一件奇怪的事情! 我们应该专注于web开发才是主流啊!

    有16位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
你瞒我瞒

这个标题真的吸引了我,我一直对Socket编程感兴趣,想从PHP开始了解一下。希望能有更多讲解相关的技巧和代码示例,这样学习会更加高效。

    有6位网友表示赞同!

“PHP”从一个简单的套接字服务器开始
雨后彩虹

这篇文章虽然简单明了,但对于完全没有网络编程基础的读者来说可能还有些难度。建议作者可以加上一些更基础的知识讲解,帮助新手更快地理解Socket服务器的概念

    有11位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/137977.html

(0)
小su's avatar小su
上一篇 2024年9月18日 下午1:58
下一篇 2024年9月18日 下午2:02

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注