首先贴上自测代码server端:
<?php
set_time_limit(0);
$ip = '127.0.0.1';
$port = 10005;
/*
+-------------------------------
* @socket通信整个过程
+-------------------------------
* @socket_create
* @socket_bind
* @socket_listen
* @socket_accept
* @socket_read
* @socket_write
* @socket_close
+--------------------------------
*/
/*---------------- 以下操作都是手册上的 -------------------*/
if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {
echo "socket_create() 失败的原因是:".socket_strerror($sock)."\n";
}
if(($ret = socket_bind($sock,$ip,$port)) < 0) {
echo "socket_bind() 失败的原因是:".socket_strerror($ret)."\n";
}
if(($ret = socket_listen($sock,4)) < 0) {
echo "socket_listen() 失败的原因是:".socket_strerror($ret)."\n";
}
$count = 0;
do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
break;
} else {
//发到客户端
$msg ="test success!\n";
socket_write($msgsock, $msg, strlen($msg));
echo "test success \n";
$buf = socket_read($msgsock,8192);
// $buf = unpack("c2chars/nint", $buf);
$arrSchema = array(
"A20username",
"A10pwd",
"Cage",
"Ibirthday",
"A50email",
);
$buf = unpack(join("/", $arrSchema), $buf);
$talkback = "receive message:".json_encode($buf)."\n";
echo $talkback;
if(++$count >= 5){
break;
};
}
//echo $buf;
socket_close($msgsock);
} while (true);
socket_close($sock);
?>
client代码:
<?php
error_reporting(E_ALL);
set_time_limit(0);
// $in = pack("nvc*", 0x1234, 0x5678, 65, 66);
// $buf = unpack("c2chars/nint", $in);
// var_dump($buf);
// exit;
echo "TCP/IP Connection\n";
$port = 10005;
$ip = "127.0.0.1";
/*
* +-------------------------------
* @socket连接整个过程
* +-------------------------------
* @socket_create
* @socket_connect
* @socket_write
* @socket_read
* @socket_close
+--------------------------------
*/
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
}else {
echo "OK.\n";
}
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
}else {
echo "connect OK \n";
}
$in = "Ho\n";
$in .= "first blood\n";
// $in = pack("nvc*", 0x1234, 0x5678, 65, 66);
/**
* 数据格式要求如下:
* 用户名:20字节,字符型
* 密码 10字节,字符型
* 年龄 1字节,无符char型
* 出生年月 4字节,整型(19800101)
* 邮箱 50字节,字符串
* 各字段间用:"\0"分割
*/
$in = '';
$in .= pack('A20',"feiyuhit") ;
$in .= pack('A10',"feiyuhit") ;
$in .= pack('C',"23") ;
$in .= pack('I',"19900101") ;
$in .= pack('A50',"feiyuhit@test.com");
$out = '';
if(!socket_write($socket, $in, strlen($in))) {
echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
}else {
echo "send success!\n";
echo "send content :$in";
}
while($out = socket_read($socket, 8192)) {
echo "request success!\n";
echo "request content:",$out;
}
echo "close SOCKET\n";
socket_close($socket);
echo "close OK\n";
?>
参考知识点:pack数据格式详解:
字符 说明
a 将字符串空白以 NULL 字符填满
A 将字符串空白以 SPACE 字符 (空格) 填满
h 十六进位字符串,低位在前
H 十六进位字符串,高位在前
c 有号字符
C 无号字符
s 有号短整数 (十六位,依计算机的位顺序)
S 无号短整数 (十六位,依计算机的位顺序)
n 无号短整数 (十六位, 高位在后的顺序)
v 无号短整数 (十六位, 低位在后的顺序)
i 有号整数 (依计算机的顺序及范围)
I 无号整数 (依计算机的顺序及范围)
l 有号长整数 (卅二位,依计算机的位顺序)
L 无号长整数 (卅二位,依计算机的位顺序)
N 无号短整数 (卅二位, 高位在后的顺序)
V 无号短整数 (卅二位, 低位在后的顺序)
f 单精确浮点数 (依计算机的范围)
d 倍精确浮点数 (依计算机的范围)
x 空位
X 倒回一位
@ 填入 NULL 字符到绝对位置
运行结果: