本来是搜一些html5 websocket资料看的,结果被引去看了php的socket编程。下面是一些简单的例子,在命令行运行php脚本就行

[命令行运行PHP]PHP中有一个php.exe文件,可以用命令执行PHP脚本。如:D:/php.exe -f F:/test.php ; 可以使用php.exe -h查看更多参数 :

server端:

<?php /** * 服务器端代码 * */ //确保在连接客户端时不会超时 set_time_limit(0); //设置IP和端口号 $address = "localhost"; $port = 1234; //调试的时候,可以多换端口来测试程序! //创建一个SOCKET if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"; die; } //阻塞模式 if (socket_set_block($sock) == false) { echo "socket_set_block() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"; die; } //绑定到socket端口 if (socket_bind($sock, $address, $port) == false) { echo "socket_bind() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"; die; } //开始监听 if (socket_listen($sock, 4) == false) { echo "socket_listen() 失败的原因是:" . socket_strerror(socket_last_error()) . "/n"; die; } do { if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "/n"; die; } //发到客户端 $msg = "welcome /n"; if (socket_write($msgsock, $msg, strlen($msg)) === false) { echo "socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n"; die; } echo "读取客户端发来的信息/n"; $buf = socket_read($msgsock, 8192); echo "收到的信息: $buf /n"; socket_close($msgsock); } while (true); socket_close($sock); ?>

client端:

<?php /** * 客户端代码 */ error_reporting(0); set_time_limit(0); echo " TCP/IP Connection /n"; $service_port = 10001; $address = '127.0.0.1'; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { die; } else { echo "OK"; } echo "试图连接 "; if (socket_connect($socket, $address, $service_port) == false) { $error = socket_strerror(socket_last_error()); echo "socket_connect() failed./n","Reason: {$error} /n"; die; } else { echo "连接OK/n"; } $in = "Hello World/r/n"; if (socket_write($socket, $in, strlen($in)) === false) { echo "socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n"; die; } else { echo "发送到服务器信息成功!/n","发送的内容为: $in /n"; } $out = ""; while ($out = socket_read($socket, 8192)) { echo "接受的内容为: ".$out; } echo "关闭SOCKET…/n"; socket_close($socket); echo "关闭OK/n"; ?>

再看websocket协议,是HTTP协议升级来的。看其消息头:

所以server端需要解析一下,并返回握手的协议内容:

在网上找到解析的相关代码 phpwebsocket - url:   http://code.google.com/p/phpwebsocket/

// Usage: $master=new WebSocket("localhost",12345); class WebSocket{ var $master; var $sockets = array(); var $users = array(); var $debug = false; function __construct($address,$port){ error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed"); socket_bind($this->master, $address, $port) or die("socket_bind() failed"); socket_listen($this->master,20) or die("socket_listen() failed"); $this->sockets[] = $this->master; $this->say("Server Started : ".date('Y-m-d H:i:s')); $this->say("Listening on : ".$address." port ".$port); $this->say("Master socket : ".$this->master."/n"); while(true){ $changed = $this->sockets; socket_select($changed,$write=NULL,$except=NULL,NULL); foreach($changed as $socket){ if($socket==$this->master){ $client=socket_accept($this->master); if($client<0){ $this->log("socket_accept() failed"); continue; } else{ $this->connect($client); } } else{ $bytes = @socket_recv($socket,$buffer,2048,0); if($bytes==0){ $this->disconnect($socket); } else{ $user = $this->getuserbysocket($socket); if(!$user->handshake){ $this->dohandshake($user,$buffer); } else{ $this->process($user,$this->unwrap($buffer)); } } } } } } function process($user,$msg){ /* Extend and modify this method to suit your needs */ /* Basic usage is to echo incoming messages back to client */ $this->send($user->socket,$msg); } function send($client,$msg){ $this->say("> ".$msg); $msg = $this->wrap($msg); socket_write($client,$msg,strlen($msg)); $this->say("! ".strlen($msg)); } function connect($socket){ $user = new User(); $user->id = uniqid(); $user->socket = $socket; array_push($this->users,$user); array_push($this->sockets,$socket); $this->log($socket." CONNECTED!"); $this->log(date("d/n/Y ")."at ".date("H:i:s T")); } function disconnect($socket){ $found=null; $n=count($this->users); for($i=0;$i<$n;$i++){ if($this->users[$i]->socket==$socket){ $found=$i; break; } } if(!is_null($found)){ array_splice($this->users,$found,1); } $index=array_search($socket,$this->sockets); socket_close($socket); $this->log($socket." DISCONNECTED!"); if($index>=0){ array_splice($this->sockets,$index,1); } } function dohandshake($user,$buffer){ $this->log("/nRequesting handshake..."); $this->log($buffer); list($resource,$host,$origin,$key1,$key2,$l8b) = $this->getheaders($buffer); $this->log("Handshaking..."); //$port = explode(":",$host); //$port = $port[1]; //$this->log($origin."/r/n".$host); $upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake/r/n" . "Upgrade: WebSocket/r/n" . "Connection: Upgrade/r/n" . //"WebSocket-Origin: " . $origin . "/r/n" . //"WebSocket-Location: ws://" . $host . $resource . "/r/n" . "Sec-WebSocket-Origin: " . $origin . "/r/n" . "Sec-WebSocket-Location: ws://" . $host . $resource . "/r/n" . //"Sec-WebSocket-Protocol: icbmgame/r/n" . //Client doesn't send this "/r/n" . $this->calcKey($key1,$key2,$l8b) . "/r/n";// . //"/r/n"; socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0))); $user->handshake=true; $this->log($upgrade); $this->log("Done handshaking..."); return true; } function calcKey($key1,$key2,$l8b){ //Get the numbers preg_match_all('/([/d]+)/', $key1, $key1_num); preg_match_all('/([/d]+)/', $key2, $key2_num); //Number crunching [/bad pun] $this->log("Key1: " . $key1_num = implode($key1_num[0]) ); $this->log("Key2: " . $key2_num = implode($key2_num[0]) ); //Count spaces preg_match_all('/([ ]+)/', $key1, $key1_spc); preg_match_all('/([ ]+)/', $key2, $key2_spc); //How many spaces did it find? $this->log("Key1 Spaces: " . $key1_spc = strlen(implode($key1_spc[0])) ); $this->log("Key2 Spaces: " . $key2_spc = strlen(implode($key2_spc[0])) ); if($key1_spc==0|$key2_spc==0){ $this->log("Invalid key");return; } //Some math $key1_sec = pack("N",$key1_num / $key1_spc); //Get the 32bit secret key, minus the other thing $key2_sec = pack("N",$key2_num / $key2_spc); //This needs checking, I'm not completely sure it should be a binary string return md5($key1_sec.$key2_sec.$l8b,1); //The result, I think } function getheaders($req){ $r=$h=$o=null; if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; } if(preg_match("/Host: (.*)/r/n/" ,$req,$match)){ $h=$match[1]; } if(preg_match("/Origin: (.*)/r/n/" ,$req,$match)){ $o=$match[1]; } if(preg_match("/Sec-WebSocket-Key1: (.*)/r/n/",$req,$match)){ $this->log("Sec Key1: ".$sk1=$match[1]); } if(preg_match("/Sec-WebSocket-Key2: (.*)/r/n/",$req,$match)){ $this->log("Sec Key2: ".$sk2=$match[1]); } if($match=substr($req,-8)) { $this->log("Last 8 bytes: ".$l8b=$match); } return array($r,$h,$o,$sk1,$sk2,$l8b); } function getuserbysocket($socket){ $found=null; foreach($this->users as $user){ if($user->socket==$socket){ $found=$user; break; } } return $found; } function say($msg=""){ echo $msg."/n"; } function log($msg=""){ if($this->debug){ echo $msg."/n"; } } function wrap($msg=""){ return chr(0).$msg.chr(255); } function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); } } class User{ var $id; var $socket; var $handshake; }

继承类:可以自己按需写,这里我添加了几行代码,sendAll()等,很方便就改成了一个即时的网页版聊天室。

// Run from command prompt > php -q chatbot.demo.php include "websocket.class.php"; // Extended basic WebSocket as ChatBot class ChatBot extends WebSocket{ function process($user,$msg){ if (isset($user->first)) { $this->send($user->socket,''); $user->first = true; } $this->say("< ".$msg); switch($msg){ case "hello" : $this->send($user->socket,"hello human"); break; case "hi" : $this->send($user->socket,"zup human"); break; case "name" : $this->send($user->socket,"my name is Multivac, silly I know"); break; case "age" : $this->send($user->socket,"I am older than time itself"); break; case "date" : $this->send($user->socket,"today is ".date("Y.m.d")); break; case "time" : $this->send($user->socket,"server time is ".date("H:i:s")); break; case "thanks": $this->send($user->socket,"you're welcome"); break; case "bye" : $this->send($user->socket,"bye"); break; //default : $this->send($user->socket,$msg." not understood"); break; default : $this->sendAll($user, $msg); break; } } function sendAll($currentUser, $msg){ $usersList = $this->users; foreach ($usersList as $user){ if ($user !== $currentUser) // 自己发送的消息就不再接收一次了 $this->send($user->socket, $msg); } } } $master = new ChatBot("localhost",12345);

客户端代码:

<html>

<head>

<title>WebSocket</title>

<style>

html,body{font:normal 0.9em arial,helvetica;}

#log {width:440px; height:200px; border:1px solid #7F9DB9; overflow:auto;}

#msg {width:330px;}

</style>

<script>

var socket;

function init(){

var host = "ws://localhost:12345/websocket/server.php";

try{

socket = new WebSocket(host);

log('WebSocket - status '+socket.readyState);

socket.onopen    = function(msg){ log("Welcome - status "+this.readyState); };

socket.onmessage = function(msg){ log("Received: "+msg.data); };

socket.onclose   = function(msg){ log("Disconnected - status "+this.readyState); };

}

catch(ex){ log(ex); }

$("msg").focus();

}

function send(){

var txt,msg;

txt = $("msg");

msg = txt.value;

if(!msg){ alert("Message can not be empty"); return; }

txt.value="";

txt.focus();

try{ socket.send(msg); log('Sent: '+msg); } catch(ex){ log(ex); }

}

function quit(){

log("Goodbye!");

socket.close();

socket=null;

}

// Utilities

function $(id){ return document.getElementById(id); }

function log(msg){ $("log").innerHTML+="<br>"+msg; }

function onkey(event){ if(event.keyCode==13){ send(); } }

</script>

</head>

<body οnlοad="init()">

<h3>WebSocket v2.00</h3>

<div id="log"></div>

<input id="msg" type="textbox" οnkeypress="onkey(event)"/>

<button οnclick="send()">Send</button>

<button οnclick="quit()">Quit</button>

<div>Commands: hello, hi, name, age, date, time, thanks, bye</div>

</body>

</html>

PS:

*  这个websocket的类文件可能有一点问题,客户端握手后应该接收的第一条信息都丢失了,没细看代码,以后再检查吧。

Websocket和PHP Socket编程相关推荐

  1. C# socket编程实践——支持广播的简单socket服务器

    在上篇博客简单理解socket写完之后我就希望写出一个websocket的服务器了,但是一路困难重重,还是从基础开始吧,先搞定C# socket编程基本知识,写一个支持广播的简单server/clie ...

  2. WebSocket 协议以及 Socket 接口

    目录 前言 一.websocket 协议 1.使用 websocket 协议请求过程解析 2.创建一个 WebSocket 对象 3.WebSocket 的实例方法 和 WebSocket 的事件 ( ...

  3. 老雷socket编程之认识常用协议

    老雷socket编程之常见网络协议 1.ip IP协议是将多个包交换网络连接起来,它在源地址和目的地址之间传送一种称之为数据包的东西, 它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求. ...

  4. WebSocket入门介绍及编程实战

    前言:最近看了几天的WebSocket,从以前的只闻其名,到现在也算是有一点点的了解了.所以就准备用博客记录一下自己的学习过程,希望也能帮助其它学习的人,因为我本人学习的过程中也是参考了很多其它人的博 ...

  5. Windows Socket编程笔记之最简单的小Demo

    Windows Socket编程的大致过程: 服务器端: ----过程-------------对应的API-------  0.初始化         |  WSAStartup()  1.创建So ...

  6. Linux下Socket编程

    Linux下Socket编程    网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...

  7. [Python_7] Python Socket 编程

    0. 说明 Python Socket 编程 1. TCP 协议 [TCP Server] 通过 netstat -ano 查看端口是否开启 # -*-coding:utf-8-*-"&qu ...

  8. 打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!

    随着HTML5 WebSocket技术的日益成熟与普及,我们能够借助WebSocket来更加方便地打通BS与CS -- 由于B/S中的WebSocket能够直接连接到C/S的服务端,并进行双向通信.例 ...

  9. C# Socket编程(5)使用TCP Socket

    TCP 协议(Transmission Control Protocol,传输控制协议)是TCP/IP体系中面向连接(connection oriented)的传输层(transport layer) ...

最新文章

  1. pandas 读写 excel 数据
  2. zigzag扫描matlab,ZIGZAG扫描的MATLAB实现 | 学步园
  3. TypeScript 入门
  4. 【SDL的编程】VC环境搭建
  5. JZOJ5143:无心行挽
  6. mysql数据库相关基础知识02
  7. 190629每日一句
  8. Webstorm全版本汉化包
  9. 无符号整型转点分十进制
  10. 医院计算机房相关制度,医院机房管理制度.docx
  11. WordPress如何变更图片存储目录uploads并取消按年月存放?
  12. excel制作项目甘特图
  13. 高校大数据专业教学实训资源解决方案
  14. java 远程视频监控系统_基于android的远程视频监控系统 附完整源码
  15. 很酷的瞄准镜样式光标效果
  16. 【机器学习】西瓜书一些关键词
  17. FTP主动和被动模式区别
  18. 游戏物理中的碰撞测试(一) - 如何检测碰撞
  19. 关系型数据库理论基础阐释
  20. VIM_readme

热门文章

  1. Python 英文文本字母跳转概率统计
  2. 中国医师节丨华为IdeaHub用远程诊疗护佑人民健康,为医生减负
  3. 每日一题-特效药申报题解
  4. JAVA我的世界突然没声音_我的世界电脑版没声音怎么办
  5. sin cos 查表法算法解析
  6. 蓝牙耳机哪个牌子运动舒适?2021音质卓越佩戴舒适这五款不要错过
  7. python实现树结构并显示
  8. 清除90天苹果充值记录_苹果内购退款2020千万要知道的技巧,不得不看!
  9. leetcode5473:灯泡开关 IV
  10. 卸载 Mac 默认的 Xcode 附带的 git