老雷socket编程之PHP利用socket扩展实现聊天服务

socket聊天服务原理

PHP有两个socket的扩展 sockets和streams
sockets
socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
socket_write
socket_read
socket_close
客户端
socket_connect($socket, $address, $service_port);

服务端
socket_bind($sock, $address, $port)
socket_listen($sock)
socket_accept

Streams
客户端
stream_socket_client
fwrite
fread
fclose($fp);
服务端
stream_socket_server
stream_set_blocking
stream_select
stream_socket_accept conn
stream_socket_recvfrom
stream_socket_sendto
stream_socket_shutdown

课后练习
使用sockets和streams扩展实现客户端跟服务端的功能。

服务端代码 客服端可使用udp&tcp测试工具

<?php

class SocketService
{
public $host="tcp://0.0.0.0:8000";
private $address;
private $port;
private $_sockets;
public $clients;
public $maxid=1000;
public function __construct($address = '', $port='')
{
if(!empty($address)){
$this->address = $address;
}
if(!empty($port)) {
$this->port = $port;
}
} public function onConnect($client_id){
echo "Client client_id:{$client_id} \n"; } public function onMessage($client_id,$msg){
//发给所有的
foreach($this->clients as $kk=>$cc){
if($kk>0){
$this->send($cc, $msg);
}
}
} public function onClose($client_id){
echo "$client_id close \n";
} public function service(){
//获取tcp协议号码。
$tcp = getprotobyname("tcp");
$sock = stream_socket_server($this->host, $errno, $errstr);; if(!$sock)
{
throw new Exception("failed to create socket: ".socket_strerror($sock)."\n");
}
stream_set_blocking($sock,0);
$this->_sockets = $sock;
echo "listen on $this->address $this->host ... \n";
} public function run(){
$this->service();
$this->clients[] = $this->_sockets;
while (true){
$changes = $this->clients;
//$write = NULL;
//$except = NULL;
stream_select($changes, $write, $except, NULL);
foreach ($changes as $key => $_sock){
if($this->_sockets == $_sock){ //判断是不是新接入的socket
if(($newClient = stream_socket_accept($_sock)) === false){
unset($this->clients[$key]);
continue;
}
$line = trim(stream_socket_recvfrom($newClient, 1024)); $this->maxid++;
$this->clients[$this->maxid] = $newClient;
$this->onConnect($this->maxid);
} else {
$msg=@stream_socket_recvfrom($_sock, 2048);
if(!$msg){
stream_socket_shutdown($this->clients[$key],STREAM_SHUT_RDWR);
unset($this->clients[$key]);
$this->onClose($key);
}else{
$msg=$this->decode($msg);
$this->onMessage($key,$msg);
} }
}
}
} /**
* 发送数据
* @param $newClinet 新接入的socket
* @param $msg 要发送的数据
* @return int|string
*/
public function send($newClinet, $msg){
$msg=$this->encode($msg);
if($msg){
stream_socket_sendto($newClinet, $msg);
} } public function encode($msg){
return $msg . "\n";
}
public function decode($msg){
return rtrim($msg, "\r\n");
} /**
* 关闭socket
*/
public function close(){
return socket_close($this->_sockets);
}
} $sock = new SocketService('127.0.0.1','9000');
$sock->run();

  

老雷socket编程之PHP利用socket扩展实现聊天服务的更多相关文章

  1. 老雷socket编程之websocket实现

    老雷socket编程之websocket实现 我们主要实现私聊和群聊两个功能,要在web端实现想微信QQ那样的即时通讯的功能,我们需要了解一下websocket.websocket是一种可以双向通讯的 ...

  2. iPhone socket 编程之BSD Socket篇

    iPhone socket 编程之BSD Socket篇 收藏在进行iPhone网络通讯程序的开发中,不可避免的要利用Socket套接字.iPhone提供了Socket网络编程的接口CFSocket, ...

  3. [深入浅出WP8.1(Runtime)]Socket编程之UDP协议

    13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只 ...

  4. PHP Socket 编程之9个主要函数的使用之测试案例

    php的socket编程算是比较难以理解的东西吧,不过,我们只要理解socket几个函数之间的关系,以及它们所扮演的角色,那么理解起来应该不是很难了,在笔者看来,socket编程,其实就是建立一个网络 ...

  5. Java Socket 编程之Socket与ServerSocket的区别

    http://www.cnblogs.com/hq-antoine/archive/2012/02/11/2346474.html 1.1 ServerSocket类    创建一个ServerSoc ...

  6. python的socket编程之udp编程

    在上篇文章中,仅仅讲述了如何进行了TCP编程,在本章中,将讲述使用udp进行编码,先看如下的代码,服务器端: root@python 513]# cat serverudp.py #!/usr/bin ...

  7. socket编程之二:两种链接类型tcp和udp

    前面一篇文章说到了一些计算机网络的基础知识.引入了socket.从这节開始,就进入正题了. 一 概述 TCP:Transimission Control Protocol传输控制协议. UPD:Use ...

  8. Linux系统编程(32)—— socket编程之TCP服务器与客户端

    TCP协议的客户端/服务器程序的一般流程 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后, ...

  9. socket编程之TCP/UDP

    目标: 1.编写TCP服务端客户端,实现客户端发送数据,服务端接收打印 2.采用OOP方式编写TCP服务端客户端,实现客户端发送数据,服务端添加时间戳,返回给客户端 3.采用OOP方式编写UDP服务端 ...

随机推荐

  1. Apache Cordova开发环境搭建(二)VS Code

    原文:Apache Cordova开发环境搭建(二)VS Code 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011127019/articl ...

  2. Qt程序调试之Q_ASSERT断言(条件为真则跳过,否则直接异常+崩溃)

    在使用Qt开发大型软件时,难免要调试程序,以确保程序内的运算结果符合我们的预期.在不符合预期结果时,就直接将程序断下,以便我们修改. 这就用到了Qt中的调试断言 - Q_ASSERT. 用一个小例子来 ...

  3. VCL to UniGUI Migration Wizard

    Free Evaluation Edition of The Automatic Migration Scripting Wizard For Converting Legacy Delphi Cod ...

  4. 最新用WPF为触摸屏写了一个手写程序,双格输入的

    原文:最新用WPF为触摸屏写了一个手写程序,双格输入的 双格输入可以提高手写速度,当前字写完以后可以自动识别提交,写下一个字.这样比单格手写速度提高一倍.特别适合触摸屏程序使用 界面如下: 程序如下: ...

  5. 入骨三分的“我们是谁”IT行业版

    这组漫画用简单的台词.粗犷的线条,把很多人心中对甲方(客户)的不满彻底地发泄了一通,并且出现了很多变种版本,引发了传播热潮. http://news.sina.com.cn/c/nd/2017-08- ...

  6. krpano全球漫游相同的声音和声音添加的场景(文章内容已移至krpano中国网站)

    请关注微信订阅号 krpano   watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG1ob2s=/font/5a6L5L2T/fontsize/400/f ...

  7. Java之线程池管理

    JDK5后建议使用ExecutorService与Excutors来创建与管理线程池, 不再建议直接使用Thread. 开始不明白原因, 今天知道结果了:使用Thread.currnetThread. ...

  8. 通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)

    原文:通通玩blend美工(6)上--仿iPhone滚动选择器的ListBox(UI设计) 好久没更新博客了,由于项目比较紧,期间收到不少园友的短消息,感谢大家对我的支持~~. 相信各位都在自己的神机 ...

  9. WPF 数据库增删改查

    <Window x:Class="DataBindingExam.MainWindow"        xmlns="http://schemas.microsof ...

  10. WPF中获取TreeView以及ListView获取其本身滚动条的方法,可实现自行调节scoll滚动的位置(可相应获取任何控件中的内部滚动条)

    原文:WPF中获取TreeView以及ListView获取其本身滚动条的方法,可实现自行调节scoll滚动的位置(可相应获取任何控件中的内部滚动条) 对于TreeView而言: TreeViewAut ...