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封装类,其实主要看字节编码类就可以了!
1public function index() {
2$socketAddr = "127.0.0.1";
3$socketPort = "10000";
4try {
5
6$selfPath = dirname ( __FILE__ );
7require ($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
45sleep ( 3 );
46$socket->disconnect (); //关闭链接
47
48 } catch ( Exception$e ) {
49var_dump($e);
50$this->log_error("pay order send to server".$e->getMessage());
51 }
Bytes.php 字节编码类
View Code
<?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 |= $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赋值类
View Code
1 <?php
2define("CONNECTED", true);
3define("DISCONNECTED", false);
4
5/**
6 * Socket class
7 *
8 *
9 * @author Seven
10*/
11Class Socket
12 {
13private static$instance;
14
15private$connection = null;
16
17private$connectionState = DISCONNECTED;
18
19private$defaultHost = "127.0.0.1";
20
21private$defaultPort = 80;
22
23private$defaultTimeout = 10;
24
25public$debug = false;
26
27function __construct()
28 {
29
30 }
31/**
32 * Singleton pattern. Returns the same instance to all callers
33 *
34 * @return Socket
35*/
36public static function singleton()
37 {
38if (self::$instance == null || ! self::$instance instanceof Socket)
39 {
40 self::$instance = new Socket();
41
43return self::$instance;
44 }
45/**
46 * Connects to the socket with the given address and port
47 *
48 * @return void
49*/
50public function connect($serverHost=false, $serverPort=false, $timeOut=false)
51 {
52if($serverHost == false)
53 {
54$serverHost = $this->defaultHost;
55 }
56
57if($serverPort == false)
58 {
59$serverPort = $this->defaultPort;
60 }
61$this->defaultHost = $serverHost;
62$this->defaultPort = $serverPort;
63
64if($timeOut == false)
65 {
66$timeOut = $this->defaultTimeout;
67 }
68$this->connection = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
69
70if(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 closedconstruct用法
85*/
86public function disconnect()
87 {
88if($this->validateConnection())
89 {
90 socket_close($this->connection);
91$this->connectionState = DISCONNECTED;
92$this->_throwMsg("Socket disconnected!");
93return true;
94 }
95return false;
96 }
97/**
98 * Sends a command to the server
99 *
100 * @return string Server response
101*/
102public function sendRequest($command)
103 {
104if($this->validateConnection())
105 {
106$result = socket_write($this->connection,$command,strlen($command));
107return$result;
108 }
109$this->_throwError("Sending command \"{$command}\" failed.<br>Reason: Not connected");
110 }
111
112
113
114public function isConn()
115 {
116return$this->connectionState;
117 }
118
119
120public function getUnreadBytes()
121 {
122
123$info = socket_get_status($this->connection);
124return$info['unread_bytes'];
125
127
128
129public function getConnName(&$addr, &$port)
130 {
131if ($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*/
144public function getResponse()
145 {
146$read_set = array($this->connection);
147
148while (($events = socket_select($read_set, $write_set = NULL, $exception_set = NULL, 0)) !== false) 149 {
150if ($events > 0)
151 {
152foreach ($read_set as$so)
153 {
154if (!is_resource($so))
155 {
156$this->_throwError("Receiving response from server failed.<br>Reason: Not connected"); 157return 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"); 160return false;
161 }
162return$ret;
163 }
164 }
165 }
166
167return false;
168 }
169public function waitForResponse()
170 {
171if($this->validateConnection())
172 {
173return socket_read($this->connection, 2048);
174 }
175
176$this->_throwError("Receiving response from server failed.<br>Reason: Not connected");
177return false;
178 }
179/**
180 * Validates the connection state
181 *
182 * @return bool
183*/
184private function validateConnection()
185 {
186return (is_resource($this->connection) && ($this->connectionState != DISCONNECTED));
187 }
188/**
189 * Throws an error
190 *
191 * @return void
192*/
193private function _throwError($errorMessage)
194 {
195echo "Socket error: " . $errorMessage;
196 }
197/**
198 * Throws an message
199 *
200 * @return void
201*/
202private function _throwMsg($msg)
203 {
204if ($this->debug)
205 {
206echo "Socket message: " . $msg . "\n\n";
207 }
208 }
209/**
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论