套接字服务器的工作方式是不间断地运行,等待客户端的连接。一旦客户端连接打开,服务器将它添加到客户列表中,然后开始等待客户端的消息。


别离开我。以下是完整的源代码:


不定执行时间限制
(0)set_time_limit;

设置IP和端口,我们将侦听
$地址= 'localhost;
$端口= 10000;
max_clients = 10美元;

它将保存客户机信息数组
$客户端=数组();

TCP流套接字创建
袜子= socket_create美元(af_inet,sock_stream,0);
套接字到一个地址
socket_bind(美元美元美元的袜子,地址,端口)或死亡(没有绑定到地址);
监听连接
socket_listen(美元的袜子);

等待连接…;

循环
当(真){
客户机侦听套接字以进行读/安装
读取$ { 0 } = $;
为($我= 0;美元美元美元我<< max_clients;i++){
如果(isset($ { $我} {客户'sock ' }))
$读{ $我+ 1 } = {我} {客户美元美元'sock};
}
一个阻塞调用 /套(socket_select)
如果(socket_select(合读、写= null美元美元,除了= null,tv_sec美元= 5)<<1)
继续;
如果正在创建一个新的连接,将其添加到客户机数组中。
如果(in_array($袜子,$读)){
为($我= 0;美元美元美元我<< max_clients;i++){
如果(空($客户{我} {美元'sock ' })){
{我} {客户美元美元'sock} = socket_accept(美元的袜子);
新客户机连接$;
打破;
}
(我= = max_clients美元- 1)
太多客户…;
}
} / /如果in_array

客户机正在尝试/如果写-现在处理它
为($我= 0;美元美元美元我<< max_clients;i++){ / /为每一个客户
如果(isset($ { $我} {客户'sock ' })){
如果(in_array($ { $我} {客户'sock},为读)){
输入= socket_read美元(美元客户{我} {美元'sock},1024);
如果($ = NULL){
客户端断开连接;
长度字符串,意思是断开连接
撤消($客户{我});
{人}
新接收到的输入;
它向其他客户机发送
(J = 0;对美元美元美元,<< max_clients;j++){
如果(isset($ { $ J } {客户'sock ' })J!= $ i){
回声写作input'to美元客户J R;
socket_write($ { $ J } {客户'sock},输入美元,strlen($输入));
}
}
如果($输入= = 'exit){
请求断开连接
socket_close($ { $我} {客户'sock});
}
}
{人}
客户端断开连接;
套接字关闭
socket_close($ { $我} {客户'sock});
撤消($客户{我});
}
}
}
结束时
主套接字 /关闭
socket_close(美元的袜子);


嗯,乍看起来,这似乎是一个大项目,但我们可以先把它分解成几个较小的部分。

第一部分是服务器的创建。行数:2到20。

代码的这一部分设置变量、地址、端口、最大客户机和客户机数组。接下来,创建套接字并将其绑定到我们指定的地址和端口。

下一步我们要做的是执行一个死循环(事实上,我们是有意的!)线条:22到32。

我们在代码的这部分做的第一步是设置读数组,这个数组包含所有客户机的套接字和主服务器的套接字。这个变量将在SELECT语句后面使用:告诉PHP监视来自这些客户机的每一条消息。

socket_select的最后一个参数()告诉我们的服务器等上5秒才返回的值。如果返回值小于1,那么就意味着没有收到数据,所以你只需要返回到循环的顶部和等待。

脚本的下一部分是将新的客户端添加到数组中。行:33到44。

将新的客户机放在列表的末端。检查以确保客户机的数量不超过我们希望服务器处理的数量。

代码块是下面的描述是相当大的,也是服务器的主要组成部分。当客户端发送到服务器的消息,这需要代码站起来处理它。消息可以是各种信息和实际断开断开,只要它是服务器的需求处理消息。线:46年底。

代码循环通过每个客户机,检查是否接收到消息。如果是,获取输入的内容。检查这是否是基于输入的中断消息,如果是的话,从数组中删除它们。相反,这是一条正常的信息。然后我们的服务器再次传递所有的客户机,并一个接一个地向他们发送消息,跳过发送者。

好了,现在试着创建你自己的聊天服务器!