PHP使用Socket发送字节流
例如,需要发送以下数据
struct header
{
int type; // 消息类型
int length; // 消息长度
}
struct MSG_Q2R2DB_PAYRESULT
{
int serialno;
int openid;
char payitem[512];
int billno;
int zoneid;
int providetype;
int coins;
}
调用的方法,另外需require两个php文件,一个是字节编码类,另外一个socket封装类,其实主要看字节编码类就可以了!
1 public function index() { 2 $socketAddr = "127.0.0.1"; 3 $socketPort = "10000"; 4 try { 5 6 $selfPath = dirname ( __FILE__ ); 7 require ($selfPath . "/../Tool/Bytes.php"); 8 $bytes = new Bytes (); 9 10 $payitem = "sdfasdfasdfsdfsdfsdfsdfsdfsdf"; 11 $serialno = 1; 12 $zoneid = 22; 13 $openid = "CFF47C448D4AA2069361567B6F8299C2"; 14 15 $billno = 1; 16 $providetype = 1; 17 $coins = 1; 18 19 $headType = 10001; 20 $headLength = 56 + intval(strlen($payitem )); 21 22 $headType = $bytes->integerToBytes ( intval ( $headType ) ); 23 $headLength = $bytes->integerToBytes ( intval ( $headLength ) ); 24 $serialno = $bytes->integerToBytes ( intval ( $serialno ) ); 25 $zoneid = $bytes->integerToBytes ( intval ( $zoneid ) ); 26 $openid = $bytes->getBytes( $openid ); 27 $payitem_len = $bytes->integerToBytes ( intval ( strlen($payitem) ) ); 28 $payitem = $bytes->getBytes($payitem); 29 $billno = $bytes->integerToBytes ( intval ( $billno ) ); 30 $providetype = $bytes->integerToBytes ( intval ( $providetype ) ); 31 $coins = $bytes->integerToBytes ( intval ( $coins ) ); 32 33 $return_betys = array_merge ($headType , $headLength , $serialno , $zoneid , $openid,$payitem_len ,$payitem,$billno,$providetype,$coins); 34 35 $msg = $bytes->toStr ($return_betys); 36 $strLen = strlen($msg); 37 38 $packet = pack("a{$strLen}", $msg); 39 $pckLen = strlen($packet); 40 41 $socket = Socket::singleton (); 42 $socket->connect ( $socketAddr, $socketPort ); //连服务器 43 $sockResult = $socket->sendRequest ( $packet); // 将包发送给服务器 44 45 sleep ( 3 ); 46 $socket->disconnect (); //关闭链接 47 48 } catch ( Exception $e ) { 49 var_dump($e); 50 $this->log_error("pay order send to server".$e->getMessage()); 51 } 52 }
Bytes.php 字节编码类
<?php/*** byte数组与字符串转化类* @author * Created on 2011-7-15*/class Bytes {/*** 转换一个String字符串为byte数组* @param $str 需要转换的字符串* @param $bytes 目标byte数组* @author Zikie*/public static function getBytes($str) {$len = strlen($str);$bytes = array();for($i=0;$i<$len;$i++) {if(ord($str[$i]) >= 128){$byte = ord($str[$i]) - 256;}else{$byte = ord($str[$i]);}$bytes[] = $byte ;}return $bytes;}/*** 将字节数组转化为String类型的数据* @param $bytes 字节数组* @param $str 目标字符串* @return 一个String类型的数据*/public static function toStr($bytes) {$str = '';foreach($bytes as $ch) {$str .= chr($ch);}return $str;}/*** 转换一个int为byte数组* @param $byt 目标byte数组* @param $val 需要转换的字符串* @author Zikie*/public static function integerToBytes($val) {$byt = array();$byt[0] = ($val & 0xff);$byt[1] = ($val >> 8 & 0xff);$byt[2] = ($val >> 16 & 0xff);$byt[3] = ($val >> 24 & 0xff);return $byt;}/*** 从字节数组中指定的位置读取一个Integer类型的数据* @param $bytes 字节数组* @param $position 指定的开始位置* @return 一个Integer类型的数据*/public static function bytesToInteger($bytes, $position) {$val = 0;$val = $bytes[$position + 3] & 0xff;$val <<= 8;$val |= $bytes[$position + 2] & 0xff;$val <<= 8;$val |= $bytes[$position + 1] & 0xff;$val <<= 8;$val |= $bytes[$position] & 0xff;return $val;}/*** 转换一个shor字符串为byte数组* @param $byt 目标byte数组* @param $val 需要转换的字符串* @author Zikie*/public static function shortToBytes($val) {$byt = array();$byt[0] = ($val & 0xff);$byt[1] = ($val >> 8 & 0xff);return $byt;}/*** 从字节数组中指定的位置读取一个Short类型的数据。* @param $bytes 字节数组* @param $position 指定的开始位置* @return 一个Short类型的数据*/public static function bytesToShort($bytes, $position) {$val = 0;$val = $bytes[$position + 1] & 0xFF;$val = $val << 8;$val |= $bytes[$position] & 0xFF;return $val;}} ?>
socket.class.php socket赋值类
1 <?php 2 define("CONNECTED", true); 3 define("DISCONNECTED", false); 4 5 /** 6 * Socket class 7 * 8 * 9 * @author Seven 10 */ 11 Class Socket 12 { 13 private static $instance; 14 15 private $connection = null; 16 17 private $connectionState = DISCONNECTED; 18 19 private $defaultHost = "127.0.0.1"; 20 21 private $defaultPort = 80; 22 23 private $defaultTimeout = 10; 24 25 public $debug = false; 26 27 function __construct() 28 { 29 30 } 31 /** 32 * Singleton pattern. Returns the same instance to all callers 33 * 34 * @return Socket 35 */ 36 public static function singleton() 37 { 38 if (self::$instance == null || ! self::$instance instanceof Socket) 39 { 40 self::$instance = new Socket(); 41 42 } 43 return self::$instance; 44 } 45 /** 46 * Connects to the socket with the given address and port 47 * 48 * @return void 49 */ 50 public function connect($serverHost=false, $serverPort=false, $timeOut=false) 51 { 52 if($serverHost == false) 53 { 54 $serverHost = $this->defaultHost; 55 } 56 57 if($serverPort == false) 58 { 59 $serverPort = $this->defaultPort; 60 } 61 $this->defaultHost = $serverHost; 62 $this->defaultPort = $serverPort; 63 64 if($timeOut == false) 65 { 66 $timeOut = $this->defaultTimeout; 67 } 68 $this->connection = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); 69 70 if(socket_connect($this->connection,$serverHost,$serverPort) == false) 71 { 72 $errorString = socket_strerror(socket_last_error($this->connection)); 73 $this->_throwError("Connecting to {$serverHost}:{$serverPort} failed.<br>Reason: {$errorString}"); 74 }else{ 75 $this->_throwMsg("Socket connected!"); 76 } 77 78 $this->connectionState = CONNECTED; 79 } 80 81 /** 82 * Disconnects from the server 83 * 84 * @return True on succes, false if the connection was already closed 85 */ 86 public function disconnect() 87 { 88 if($this->validateConnection()) 89 { 90 socket_close($this->connection); 91 $this->connectionState = DISCONNECTED; 92 $this->_throwMsg("Socket disconnected!"); 93 return true; 94 } 95 return false; 96 } 97 /** 98 * Sends a command to the server 99 * 100 * @return string Server response 101 */ 102 public function sendRequest($command) 103 { 104 if($this->validateConnection()) 105 { 106 $result = socket_write($this->connection,$command,strlen($command)); 107 return $result; 108 } 109 $this->_throwError("Sending command \"{$command}\" failed.<br>Reason: Not connected"); 110 } 111 112 113 114 public function isConn() 115 { 116 return $this->connectionState; 117 } 118 119 120 public function getUnreadBytes() 121 { 122 123 $info = socket_get_status($this->connection); 124 return $info['unread_bytes']; 125 126 } 127 128 129 public function getConnName(&$addr, &$port) 130 { 131 if ($this->validateConnection()) 132 { 133 socket_getsockname($this->connection,$addr,$port); 134 } 135 } 136 137 138 139 /** 140 * Gets the server response (not multilined) 141 * 142 * @return string Server response 143 */ 144 public function getResponse() 145 { 146 $read_set = array($this->connection); 147 148 while (($events = socket_select($read_set, $write_set = NULL, $exception_set = NULL, 0)) !== false) 149 { 150 if ($events > 0) 151 { 152 foreach ($read_set as $so) 153 { 154 if (!is_resource($so)) 155 { 156 $this->_throwError("Receiving response from server failed.<br>Reason: Not connected"); 157 return false; 158 }elseif ( ( $ret = @socket_read($so,4096,PHP_BINARY_READ) ) == false){ 159 $this->_throwError("Receiving response from server failed.<br>Reason: Not bytes to read"); 160 return false; 161 } 162 return $ret; 163 } 164 } 165 } 166 167 return false; 168 } 169 public function waitForResponse() 170 { 171 if($this->validateConnection()) 172 { 173 return socket_read($this->connection, 2048); 174 } 175 176 $this->_throwError("Receiving response from server failed.<br>Reason: Not connected"); 177 return false; 178 } 179 /** 180 * Validates the connection state 181 * 182 * @return bool 183 */ 184 private function validateConnection() 185 { 186 return (is_resource($this->connection) && ($this->connectionState != DISCONNECTED)); 187 } 188 /** 189 * Throws an error 190 * 191 * @return void 192 */ 193 private function _throwError($errorMessage) 194 { 195 echo "Socket error: " . $errorMessage; 196 } 197 /** 198 * Throws an message 199 * 200 * @return void 201 */ 202 private function _throwMsg($msg) 203 { 204 if ($this->debug) 205 { 206 echo "Socket message: " . $msg . "\n\n"; 207 } 208 } 209 /** 210 * If there still was a connection alive, disconnect it 211 */ 212 public function __destruct() 213 { 214 $this->disconnect(); 215 } 216 } 217 218 ?>
PacketBase.class.php 打包类,暂时没用到
1 <?php 2 /** 3 * PacketBase class 4 * 5 * 用以处理与c++服务端交互的sockets 包 6 * 7 * 注意:不支持宽字符 8 * 9 * @author Seven <seven@qoolu.com> 10 * 11 */ 12 class PacketBase extends ContentHandler 13 { 14 private $head; 15 private $params; 16 private $opcode; 17 /**************************construct***************************/ 18 function __construct() 19 { 20 $num = func_num_args(); 21 $args = func_get_args(); 22 switch($num){ 23 case 0: 24 //do nothing 用来生成对象的 25 break; 26 case 1: 27 $this->__call('__construct1', $args); 28 break; 29 case 2: 30 $this->__call('__construct2', $args); 31 break; 32 default: 33 throw new Exception(); 34 } 35 } 36 //无参数 37 public function __construct1($OPCODE) 38 { 39 $this->opcode = $OPCODE; 40 $this->params = 0; 41 } 42 //有参数 43 public function __construct2($OPCODE, $PARAMS) 44 { 45 $this->opcode = $OPCODE; 46 $this->params = $PARAMS; 47 } 48 //析构 49 function __destruct() 50 { 51 unset($this->head); 52 unset($this->buf); 53 } 54 55 //打包 56 public function pack() 57 { 58 $head = $this->MakeHead($this->opcode,$this->params); 59 return $head.$this->buf; 60 } 61 //解包 62 public function unpack($packet,$noHead = false) 63 { 64 65 $this->buf = $packet; 66 if (!$noHead){ 67 $recvHead = unpack("S2hd/I2pa",$packet); 68 $SD = $recvHead[hd1];//SD 69 $this->contentlen = $recvHead[hd2];//content len 70 $this->opcode = $recvHead[pa1];//opcode 71 $this->params = $recvHead[pa2];//params 72 73 $this->pos = 12;//去除包头长度 74 75 if ($SD != 21316) 76 { 77 return false; 78 } 79 }else 80 { 81 $this->pos = 0; 82 } 83 return true; 84 } 85 public function GetOP() 86 { 87 if ($this->buf) 88 { 89 return $this->opcode; 90 } 91 return 0; 92 } 93 /************************private***************************/ 94 //构造包头 95 private function MakeHead($opcode,$param) 96 { 97 return pack("SSII","SD",$this->TellPut(),$opcode,$param); 98 } 99 100 //用以模拟函数重载 101 private function __call($name, $arg) 102 { 103 return call_user_func_array(array($this, $name), $arg); 104 } 105 106 107 /***********************Uitl***************************/ 108 //将16进制的op转成10进制 109 static function MakeOpcode($MAJOR_OP, $MINOR_OP) 110 { 111 return ((($MAJOR_OP & 0xffff) << 16) | ($MINOR_OP & 0xffff)); 112 } 113 } 114 /** 115 * 包体类 116 * 包含了对包体的操作 117 */ 118 class ContentHandler 119 { 120 public $buf; 121 public $pos; 122 public $contentlen;//use for unpack 123 124 function __construct() 125 { 126 $this->buf = ""; 127 $this->contentlen = 0; 128 $this->pos = 0; 129 } 130 function __destruct() 131 { 132 unset($this->buf); 133 } 134 135 public function PutInt($int) 136 { 137 $this->buf .= pack("i",(int)$int); 138 } 139 public function PutUTF($str) 140 { 141 $l = strlen($str); 142 $this->buf .= pack("s",$l); 143 $this->buf .= $str; 144 } 145 public function PutStr($str) 146 { 147 return $this->PutUTF($str); 148 } 149 150 151 public function TellPut() 152 { 153 return strlen($this->buf); 154 } 155 156 157 /*******************************************/ 158 159 public function GetInt() 160 { 161 //$cont = substr($out,$l,4); 162 $get = unpack("@".$this->pos."/i",$this->buf); 163 if (is_int($get[1])){ 164 $this->pos += 4; 165 return $get[1]; 166 } 167 return 0; 168 } 169 public function GetShort() 170 { 171 $get = unpack("@".$this->pos."/S",$this->buf); 172 if (is_int($get[1])){ 173 $this->pos += 2; 174 return $get[1]; 175 } 176 return 0; 177 } 178 public function GetUTF() 179 { 180 $getStrLen = $this->GetShort(); 181 182 if ($getStrLen > 0) 183 { 184 $end = substr($this->buf,$this->pos,$getStrLen); 185 $this->pos += $getStrLen; 186 return $end; 187 } 188 return ''; 189 } 190 /***************************/ 191 192 public function GetBuf() 193 { 194 return $this->buf; 195 } 196 197 public function SetBuf($strBuf) 198 { 199 $this->buf = $strBuf; 200 } 201 202 public function ResetBuf(){ 203 $this->buf = ""; 204 $this->contentlen = 0; 205 $this->pos = 0; 206 } 207 208 } 209 210 ?>
可能你看的有点迷糊,因为我也不知道该怎么解释,有空梳理一下~
转载于:https://www.cnblogs.com/yimu/archive/2013/01/04/2843758.html
PHP使用Socket发送字节流相关推荐
- java socket发送16进制_JavaSocket短连接实现分别接收字符串和16进制数据
做个笔记,在接收16进制数据的时候乱码了.原因是Socket在接收数据的时候需要根据不同的数据定义不同的接收方式,也就是约定好传输协议(具体体现在后面服务端接收16进制那里). 字符串的发送接收 字符 ...
- python socket发送16进制数据_Python UDP Socket 16进制数据发送
注:此篇文章首次发表于我的一篇CSDN博客里边,现转载于此. 今天琢磨了一下Python UDP Socket 16进制数据发送. 原以为UDP发送和接受的都是字符,怎么能够发送16进制?但细想,其实 ...
- python怎么发送代码文件_python 通过 socket 发送文件的实例代码
目录结构: client: #!/usr/bin/env python # -*-coding:utf-8 -*- import socket, struct, json download_dir = ...
- python udp 直播_[Python] socket发送UDP广播实现聊天室功能
原博文 2018-11-24 12:33 − 一.说明 本文主要使用socket.socket发送UDP广播来实现聊天室功能. 重点难点:理解UDP通讯流程.多线程.UDP广播收发等. 测试环境:Wi ...
- 安卓使用Socket发送中文,C语言服务端接收乱码问题解决方式
今天用安卓通过Socket发送数据到电脑上使用C语言写的服务端,发送英文没有问题,可当把数据改变成中文时,服务端接收到的数据确是乱码. 突然想到.VS的预处理使用的是ANSI编码.而安卓网络数据都是U ...
- python socket发送组播数据_python3通过udp实现组播数据的发送和接收操作
本文主要通过对海康摄像头进行抓包,模拟发送了udp包,并抓取摄像头返回的数据包,解析并提取相关信息. 通过抓包发现,海康摄像头发送.接收数据使用udp协议,后来比较发现,使用python模拟起来比较简 ...
- Windows下C 用 Socket 发送图片--基础
Windows下C 用 Socket 发送图片--基础 转载:http://blog.csdn.net/yulinxx/article/details/51338214 服务器端: #include ...
- socket发送请求,协程
1.socket发送请求 1 #发送请求的方式 2 3 #方式一 4 import requests 5 6 ret = requests.get("https://www.baidu.co ...
- socket php验证客户端验证,用Socket发送电子邮件(利用需要验证的SMTP服务器)_php基础...
* 名称:用Socket发送电子邮件 * 描述:本类实现了直接使用需要验证的SMTP服务器直接发送邮件,参考文章<用Socket发送电子邮件>作者:limodou * 此文章比较早,他是用 ...
- linux非阻塞的socket发送数据出现EAGAIN错误的处理方法
一.非阻塞socket 非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回.比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上.在 ...
最新文章
- [asp.net core]SignalR一个例子
- 分享一个python cookbook的在线教程地址
- 〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法...
- php中echo js代码,JS有没类似PHP的echo效果?
- php post api json数据,php – REST API:请求身份为JSON或纯POST数据?
- 【做题记录】CF1428E Carrots for Rabbits—堆的妙用
- C/C++中指针和引用之相关问题研究
- POJ 1789(最小生成树)
- 【PAT乙】1038 统计同成绩学生 (20分) 裸桶排序
- .NET Enterprise 4.1.5的工作流引擎
- 思科防火墙基本配置思路及命令
- 颜色代码查询,在线颜色选择器,RGB颜色对照表
- (转载)巴西世界杯谁能夺冠?霍金和高盛做预测
- 泰戈尔《园丁集》选段
- MPP 与 Hadoop是什么关系?
- basic计算机编程基础,计算机编程基础(Visual Basic)
- JUnit:求求你了,别再用 main 方法测试了,好吗?
- AXI总线信号含义说明
- Real诉讼暴风影音侵权一案今日开庭
- Apache Pulsar 2.7.1 版本正式发布!
热门文章
- 对计算机科学与技术专业的认识和思考,计算机科学和技术专业的认识和思考.doc...
- 【.Net】asp.net 把图片从CMYK印刷模式转换为RGB原色模式
- 【GIS风暴】什么是EPSG?常见坐标系对应的EPSG代号、经度范围、中央经线是多少?
- 【第七周】项目6-停车场模拟
- CF 346 B vectorpair s[100]
- 2022-2028年中国安防行业全景调研及竞争格局预测报告
- 设计测试用例需要注意的点
- Java setlocale方法_Java MessageFormat setLocale()用法及代码示例
- 软体机器人与类脑智能机器人
- 数字孪生3D可视化智慧化社区管理平台