PHP socket 接收 java端口 netty 网络字节序
java 服务端测试代码:
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { buffer.writeShort(5); buffer.writeInt(-51321); buffer.writeFloat(-123); buffer.writeDouble(-1121); buffer.writeBytes("测试测试ing123".getBytes()); ctx.write(buffer, promise); }
PHP 端接收代码:
<?php $host = 'xxxx'; $port = 9876; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket.\n"); $connection = socket_connect($socket, $host, $port) or die("Could not connect server.\n"); //socket_write($socket, json_encode(['age'=>"333", 'name'=>'aaa', "bb"=>121])) or die("Write failed.\n"); $ret = socket_recv($socket, $msg, 130, MSG_PEEK ); $bytes = Bytes::initBytes($msg); $short = $bytes->readShort(); $int = $bytes->readInt(); $float = $bytes->readFloat(); $double = $bytes->readDouble(); $string = $bytes->readString(100); var_dump($double);die(); class Bytes{ private $buffer = null; private $readIdx= 0; private $maxLength = 0; const BIG_ENDIAN = 1 ; const LITTLE_ENDIAN = 2; const WAITING_CHECK = -1; private static $result = -1; const INT_LEN = 4; const SHORT_LEN= 2; const FLOAT_LEN = 4; const DOUBLE_LEN = 8; //判断本地字节序 public static function getEndian(){ if( static::$result == static::WAITING_CHECK ){ static::$result = self::LITTLE_ENDIAN; if( pack('L', 1) === pack('N', 1) ){ static::$result == static::BIG_ENDIAN; } } return static::$result; } public static function initBytes( $buffers ){ return new static( $buffers ); } private function __construct($buff){ $this->buffer = $buff; $this->maxLength = strlen($buff); } public function readShort(){ $short = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $short = unpack( 's' , substr( $this->buffer, $this->readIdx, static::SHORT_LEN ) ); }else{ $short = unpack( 's', strrev( substr( $this->buffer, $this->readIdx, static::SHORT_LEN ) )); } $this->updateReadIdx(static::SHORT_LEN); return $short; } public function readInt(){ $int = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $int = unpack( 'i' , substr( $this->buffer, $this->readIdx, static::INT_LEN ) ); }else{ $int = unpack( 'i', strrev( substr( $this->buffer, $this->readIdx, static::INT_LEN ) )); } $this->updateReadIdx(static::INT_LEN); return $int; } public function readString( $length = 100 ){ $str = ""; $len = min( $length, $this->maxLength - $this->readIdx ); for( $i = $this->readIdx; $i < $this->readIdx+$len; $i++ ){ $str .= $this->buffer[$i]; } $this->updateReadIdx($len); return $str; } public function readFloat(){ $float = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $float = unpack( 'f' , substr( $this->buffer, $this->readIdx, static::FLOAT_LEN ) ); }else{ $float = unpack( 'f', strrev( substr( $this->buffer, $this->readIdx, static::FLOAT_LEN ) )); } $this->updateReadIdx(static::FLOAT_LEN); return $float; } public function readDouble(){ $double = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $double = unpack( 'd' , substr( $this->buffer, $this->readIdx, static::DOUBLE_LEN ) ); }else{ $double = unpack( 'd', strrev( substr( $this->buffer, $this->readIdx, static::DOUBLE_LEN ) )); } $this->updateReadIdx(static::DOUBLE_LEN); return $double; } private function updateReadIdx( $length ){ $this->readIdx += $length; } } ?>
PHP 本地测试 :
/** * @author sukura */ $bytes = Bytes::initBytes(); $bytes->writeDouble(-5.123)->writeInt(5.3)->writeFloat(-12.123); var_dump($bytes->readDouble()); var_dump($bytes->readInt()); var_dump($bytes->readFloat()); class Bytes{ private $buffer = null; private $readIdx= 0; private $maxLength = 0; const BIG_ENDIAN = 1 ; const LITTLE_ENDIAN = 2; const WAITING_CHECK = -1; private static $result = -1; const INT_LEN = 4; const SHORT_LEN= 2; const FLOAT_LEN = 4; const DOUBLE_LEN = 8; public static function getEndian(){ if( static::$result == static::WAITING_CHECK ){ static::$result = self::LITTLE_ENDIAN; if( pack('L', 1) === pack('N', 1) ){ static::$result == static::BIG_ENDIAN; } } return static::$result; } public static function initBytes( $buffers = null ){ return new static( $buffers ); } private function __construct( $buff = null ){ $this->buffer = $buff; $this->maxLength = strlen($buff); } public function readShort(){ $short = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $short = unpack( 's' , substr( $this->buffer, $this->readIdx, static::SHORT_LEN ) ); }else{ $short = unpack( 's', strrev( substr( $this->buffer, $this->readIdx, static::SHORT_LEN ) )); } $this->updateReadIdx(static::SHORT_LEN); return $short; } public function readInt(){ $int = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $int = unpack( 'i' , substr( $this->buffer, $this->readIdx, static::INT_LEN ) ); }else{ $int = unpack( 'i', strrev( substr( $this->buffer, $this->readIdx, static::INT_LEN ) )); } $this->updateReadIdx(static::INT_LEN); return $int; } public function readString( $length = 100 ){ $str = ""; $len = min( $length, $this->maxLength - $this->readIdx ); for( $i = $this->readIdx; $i < $this->readIdx+$len; $i++ ){ $str .= $this->buffer[$i]; } $this->updateReadIdx($len); return $str; } public function readFloat(){ $float = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $float = unpack( 'f' , substr( $this->buffer, $this->readIdx, static::FLOAT_LEN ) ); }else{ $float = unpack( 'f', strrev( substr( $this->buffer, $this->readIdx, static::FLOAT_LEN ) )); } $this->updateReadIdx(static::FLOAT_LEN); return $float; } public function readDouble(){ $double = 0; if( static::getEndian() == static::BIG_ENDIAN ){ $double = unpack( 'd' , substr( $this->buffer, $this->readIdx, static::DOUBLE_LEN ) ); }else{ $double = unpack( 'd', strrev( substr( $this->buffer, $this->readIdx, static::DOUBLE_LEN ) )); } $this->updateReadIdx(static::DOUBLE_LEN); return $double; } public function writeInt( $intVal ){ $byte = null; if( static::getEndian() == static::BIG_ENDIAN ){ $byte = pack('i', $intVal); }else{ $byte = strrev( pack( 'i' , $intVal ) ); } $this->mergeByte($byte); return $this; } public function writeFloat( $floatVal ){ $byte = null; if( static::getEndian() == static::BIG_ENDIAN ){ $byte = pack('f', $floatVal); }else{ $byte = strrev( pack( 'f' , $floatVal ) ); } $this->mergeByte($byte); return $this; } public function writeString( $strVal ){ $byte = null; $len = strlen($strVal); $formate = "a{$len}"; if( static::getEndian() == static::BIG_ENDIAN ){ $byte = pack($formate, $strVal); }else{ $byte = strrev( pack( $formate , $strVal ) ); } $this->mergeByte($byte); return $this; } public function writeDouble( $doubleVal ){ $byte = null; if( static::getEndian() == static::BIG_ENDIAN ){ $byte = pack('d', $doubleVal); }else{ $byte = strrev( pack( 'd' , $doubleVal ) ); } $this->mergeByte($byte); return $this; } private function mergeByte( $bytes ){ return $this->buffer .= $bytes; } private function updateReadIdx( $length ){ $this->readIdx += $length; } }
生命只有一次。