设为首页 收藏本站
查看: 730|回复: 0

[经验分享] php和c++socket通讯(基于字节流,二进制)

[复制链接]

尚未签到

发表于 2017-4-10 08:01:57 | 显示全部楼层 |阅读模式
  研究了一下PHP和C++socket通讯,用C++作为服务器端,php作为客户端进行.
  socket通讯是基于协议的,因此,只要双方协议一致就行.
  关于协议的选择:我看过网上大部分协议都是在应用层的协议,选用这样的协议很方便,基本上就是字符串传过来,传过去
  本次研究的协议算是当今国际化的一个标准做法.length+flag+body(长度+类型+内容)的方式,
  


total_lengthcodeflaglength1string1length2string2
总长度操作类型标志字符串1长度字符串1字符串2长度字符串2
4字节2字节4字节(暂时无用)2字节x字节2字节x字节


  php实现方式,也很容易,通过pack打包成二进制进行通讯.下面贴一下代码
  本地测试主要应用为:发送账号和密码给服务器端

<?php  
class Byte{  
//长度   
private $length=0;  
private $byte='';  
//操作码   
private $code;  
public function setBytePrev($content){  
$this->byte=$content.$this->byte;  
}  
public function getByte(){  
return $this->byte;  
}  
public function getLength(){  
return $this->length;  
}  
public function writeChar($string){  
$this->length+=strlen($string);  
$str=array_map('ord',str_split($string));  
foreach($str as $vo){  
$this->byte.=pack('c',$vo);  
}  
$this->byte.=pack('c','0');  
$this->length++;  
}  
public function writeInt($str){  
$this->length+=4;  
$this->byte.=pack('L',$str);  
}  
public function writeShortInt($interge){  
$this->length+=2;  
$this->byte.=pack('v',$interge);  
}  
}  
class GameSocket{  
private $socket;  
private $port=9991;  
private $host='192.168.211.231';  
private $byte;  
private $code;  
const CODE_LENGTH=2;  
const FLAG_LENGTH=4;  
public function __set($name,$value){  
$this->$name=$value;  
}  
public function __construct($host='192.168.211.231',$port=9991){  
$this->host=$host;  
$this->port=$port;  
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
if(!$this->socket){  
exit('创建socket失败');  
}  
$result = socket_connect($this->socket,$this->host,$this->port);  
if(!$result){  
exit('连接不上目标主机'.$this->host);  
}  
$this->byte=new Byte();  
}  
public function write($data){  
if(is_string($data)||is_int($data)||is_float($data)){  
$data[]=$data;  
}  
if(is_array($data)){  
foreach($data as $vo){  
$this->byte->writeShortInt(strlen($vo));  
$this->byte->writeChar($vo);  
}  
}  
$this->setPrev();  
$this->send();  
}  
/*
*设置表头部分
*表头=length+code+flag
*length是总长度(4字节)  code操作标志(2字节)  flag暂时无用(4字节)
*/  
private function getHeader(){  
$length=$this->byte->getLength();  
$length=intval($length)+self::CODE_LENGTH+self::FLAG_LENGTH;  
return pack('L',$length);  
}  
private function getCode(){  
return pack('v',$this->code);  
}  
private function getFlag(){  
return pack('L',24);  
}  
private function setPrev(){  
$this->byte->setBytePrev($this->getHeader().$this->getCode().$this->getFlag());  
}  
private function send(){  
$result=socket_write($this->socket,$this->byte->getByte());  
if(!$result){  
exit('发送信息失败');  
}  
}  
public function __desctruct(){  
socket_close($this->socket);  
}  
}  
$data[]='testzouhao';  
$data[]='a';  
$gameSocket=new GameSocket();  
$gameSocket->code=11;  
$gameSocket->write($data);  

  通过抓包分析,得到本次的包内容
DSC0000.jpg

  包头等等都不用看了,主要看蓝色部分.
  根据协议分析,前4个字节为表头,代表的是长度
  因此:
  17 00 00 00代表的是表头长度,17为16进制,转换为十进制为23,代表其余部分全部加为23字节.
  0b 00代表的是操作码为11,代表是登录操作
  18 00 00 00代表的是flag,暂时无用,不去理会
  0a 00 代表的字符串1的长度,转为十进制为10
  74 65 73 74 7a 6f 75 68 61 6f 分别转为十进制之后,是ascii码对应的字符,结果为:testzouhao,
  由于C++字符串的机制是末尾是\0,所以在字符串后,00字节就是\0
  然后是第二个字符串长度为01 00,也就是为1
  61同理,十进制转ascii码,为a,之后的00为c++机制的\0
  完美解析,发送包无措,之后c++服务器也返回了相应的包,我在按照同理进行解包就可以了!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362633-1-1.html 上篇帖子: PHP二次开发看卢松松的VIP收费 下篇帖子: 删除数组元素实用的PHP数组函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表