php实现与erlang的二进制通讯实例解析


Posted in PHP onJuly 23, 2014

一般来说网络通讯常用的方式有2种:文本通讯和二进制通讯。php与erlang之间实现文本通讯比较简单,这里就不做讨论,本文主要讨论的是php与erlang实现二进制通讯的实现方法。实现步骤如下:

erlang端代码:

-module(server).

-export([start/0]).
-define( UINT, 32/unsigned-little-integer).

-define( INT, 32/signed-little-integer).

-define( USHORT, 16/unsigned-little-integer).

-define( SHORT, 16/signed-little-integer).

-define( UBYTE, 8/unsigned-little-integer).

-define( BYTE, 8/signed-little-integer).
-define( PORT, 5678).
%% 启动服务并接受客户端的连接

start() ->

  {ok, LSock} = gen_tcp:listen(?PORT, [binary, {packet, 0},{active, false}]),

  io:format("socket listen: ~p on ~p ~n",[LSock, ?PORT]),

  accept(LSock).
accept(LSock) ->

  {ok, ASock} = gen_tcp:accept(LSock),

  spawn(fun() -> server_loop(ASock) end),

  accept(LSock).
server_loop(ASock) ->

  case gen_tcp:recv(ASock, 0) of

    {ok, <<Len:?USHORT,Cmd:?USHORT,Contain:4/binary-unit:8>> = A} ->

      io:format("recv data: ~p ~p ~p~n", [Len, Cmd, Contain]),

      %%将接收到数据发送回客户端

      gen_tcp:send(ASock, A),

      server_loop(ASock);

    {ok, Data} ->

      io:format("recv unformated data: ~p~n", [Data]),

      server_loop(ASock);

    {error, _} ->

      {ok, recv_error}

    end.

php端代码:

<?php

$timeout = 3;
//超时时间:3秒

$fp = fsockopen("tcp://127.0.0.1", 5678, $errno, $errstr, $timeout/* 连接超时时间 */);
if (!$fp) {
 echo "$errstr ($errno)<br />\n";
} else {
 stream_set_timeout($fp, $timeout);
 //远程数据接收或发送超时时间

 $format = "vva4";
 $data = pack($format, 4, 10001, "abcd");
 //$data 按照一定格式被打包成二进制数据

 fwrite($fp, $data);

 if (!feof($fp)) {

  $rs = fread($fp, 1024);
  //读取远程数据
  if ($rs) {

   $len = strlen($rs);
   //$len 可以获取数据的长度,用以计算content的长度
   //在这个例子中,content 的长度为 4

   $format = "vlen/vcmd/a4content";
   $data = unpack($format, $rs);

   print_r($data);
  } else {
   echo "timeout!";
  }
 } else {
  echo "timeout!";
 }
 fclose($fp);
}
?>

运行正常的情况下,php端会显示以下内容:

Array ( [len] => 4 [cmd] => 10001 [content] => abcd )

针对通讯的一些说明

这里用到的是php的pack函数和unpack函数:

pack函数:将数据按照一定格式打包成二进制数据,生成的数据接近C/C++的结构体数据(C/C++字符串带结束符)。

unpack函数:与pack相反,对二进制数据进行解包。

对应的erlang端,则直接用位语法来匹配二进制数据即可

PHP 相关文章推荐
如何获得PHP相关资料
Oct 09 PHP
自动把纯文本转换成Web页面的php代码
Aug 27 PHP
发一个php简单的伪原创程序,配合商城采集用的
Oct 12 PHP
PHP将DateTime对象转化为友好时间显示的实现代码
Sep 20 PHP
ThinkPHP CURD方法之page方法详解
Jun 18 PHP
php实现的短网址算法分享
Jun 20 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
PHP设置进度条的方法
Jul 08 PHP
Zend Framework教程之Zend_Db_Table用法详解
Mar 21 PHP
php 文件下载 出现下载文件内容乱码损坏的解决方法(推荐)
Nov 16 PHP
php中序列化与反序列化详解
Feb 13 PHP
Laravel使用PHPQRCODE实现生成带有LOGO的二维码图片功能示例
Jul 07 PHP
PHP使用CURL实现对带有验证码的网站进行模拟登录的方法
Jul 23 #PHP
Yii使用CLinkPager分页实例详解
Jul 23 #PHP
ThinkPHP单字母函数(快捷方法)使用总结
Jul 23 #PHP
PHP中的use关键字概述
Jul 23 #PHP
ThinkPHP实现将SESSION存入MYSQL的方法
Jul 22 #PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
Jul 22 #PHP
ThinkPHP权限认证Auth实例详解
Jul 22 #PHP
You might like
php中call_user_func函数使用注意事项
2014/11/21 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
Javascript 构造函数 实例分析
2008/11/26 Javascript
JavaScript实现表格排序方法
2013/06/14 Javascript
JavaScript加强之自定义callback示例
2013/09/21 Javascript
JS控制图片翻转示例代码(兼容firefox,ie,chrome)
2013/12/19 Javascript
Bootstrap零基础入门教程(三)
2016/07/18 Javascript
jQuery实现的自动加载页面功能示例
2016/09/04 Javascript
AngularJS中$watch和$timeout的使用示例
2016/09/20 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
脚本div实现拖放功能(两种)
2017/02/13 Javascript
JavaScript操作文件_动力节点Java学院整理
2017/06/30 Javascript
微信小程序网络封装(简单高效)
2018/08/06 Javascript
Vue.js 事件修饰符的使用教程
2018/11/01 Javascript
JS FormData对象使用方法实例详解
2020/02/12 Javascript
uni-app使用微信小程序云函数的步骤示例
2020/05/22 Javascript
JS实现页面鼠标点击出现图片特效
2020/08/19 Javascript
python中Genarator函数用法分析
2015/04/08 Python
用C++封装MySQL的API的教程
2015/05/06 Python
python动态加载包的方法小结
2016/04/18 Python
Python 类的继承实例详解
2017/03/25 Python
python3 selenium 切换窗口的几种方法小结
2018/05/21 Python
Python数据分析matplotlib设置多个子图的间距方法
2018/08/03 Python
python 标准差计算的实现(std)
2019/07/29 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
使用Tkinter制作信息提示框
2020/02/18 Python
使用 Python 在京东上抢口罩的思路详解
2020/02/27 Python
Python学习之路之pycharm的第一个项目搭建过程
2020/06/18 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
2021/02/22 Python
日本最大美瞳直送网:Morecontact(中文)
2019/04/03 全球购物
Ruby如何实现动态方法调用
2012/11/18 面试题
入党申请人的自我鉴定
2013/12/01 职场文书
党支部三会一课计划
2014/09/24 职场文书
采购员岗位职责
2015/02/03 职场文书
2016年秋季运动会加油稿
2015/12/21 职场文书
浅谈redis缓存在项目中的使用
2021/05/20 Redis