PHP使用Socket发送字节流_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3774 | 回复: 0   主题: PHP使用Socket发送字节流        下一篇 
snisn
注册用户
等级:新兵
经验:51
发帖:84
精华:0
注册:2011-10-23
状态:离线
发送短消息息给snisn 加好友    发送短消息息给snisn 发消息
发表于: IP:您无权察看 2014-10-8 9:35:10 | [全部帖] [楼主帖] 楼主

例如,需要发送以下数据

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 ?>


可能你看的有点迷糊,因为我也不知道该怎么解释,有空梳理一下。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论