PHP socket代码怎么写 才能接受客户端websocket发过来的数据 他这个我用过不行 客户端发过来的数据根本收不到 要自己改得。。我想写原生 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 /** * TCP操作基类 * @package SHIT\Protocol * @see \SHIT\Object */class TCPv4 extends \X\Core\Object { /** * 套接字句柄 * @var resource */ protected $rLink = null; /** * 构造函数 * @param string $ip IP地址 * @param int $port 端口号 * * @throws \X\Exception\Abstraction */ public function __construct($ip, $port) { $this->rLink = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if( false === $this->rLink ) { $this->rLink = null; $this->SetSocketError(__LINE__); throw new \X\Exception\Error($this->sError, $this->iErrno); } //设置连接超时为1秒 if( !$this->SetSendTimeout(1) ) { $this->Close(); throw new \X\Exception\Error($this->sError, $this->iErrno); }// echo 'sssssssssssss'; if( !@socket_connect($this->rLink, $ip, $port) ) { $this->SetSocketError(__LINE__); $this->Close(); throw new \X\Exception\Error($this->sError, $this->iErrno); }// var_dump($this->rLink);exit; if( !$this->SetSendTimeout(1) || !$this->SetRecvTimeout(3) ) { $this->Close(); throw new \X\Exception\Error($this->sError, $this->iErrno); } } /** * 析构函数 */ public function __destruct() { $this->Close(); } /** * 发送数据 * @param string $buffer 待发送数据的缓存 * @param int $flags 参数,默认为0 * * @return bool 发送成功返回true,否则返回false */ public function Send($buffer, $flags=0) { $buffer = strval($buffer); $bufLen = strlen($buffer); if( $bufLen <= 0 ) { return true; } $finishIndex = 0; $bytes = null;$zeroTimes = 0; do { if( $finishIndex > 0 ) { usleep(100); } $bytes = @socket_send($this->rLink, substr($buffer, $finishIndex), $bufLen - $finishIndex, $flags); if( false === $bytes ) { $this->SetSocketError(__LINE__); return false; } else if( $bytes <= 0 ) { ++$zeroTimes; if( $zeroTimes > 100 ) { $this->SetError('Send data 0 bytes more than 100 times', __LINE__); return false; } } else { $finishIndex += $bytes; } }while($finishIndex < $bufLen); return true; } /** * 获取数据 * @param string &$buffer 保存接收数据的缓存(注意:函数中会将此缓存清空后再存放接收到的数据) * @param int $length 接收数据长度 * @param int $flags 参数,默认为0 * * @return bool 发送成功返回true,否则返回false */ public function Recv(&$buffer, $length, $flags=0) { $length = intval($length); if( $length <= 0 ) { return true; } $buffer = '';$bytes = -1;$cache = '';$zeroTimes = 0; do { if( $bytes > 0 ) { usleep(100); } $bytes = @socket_recv($this->rLink, $cache, $length, $flags); if( false === $bytes ) { $this->SetSocketError(__LINE__); return false; } else if( $bytes <= 0 ) { ++$zeroTimes; if( $zeroTimes > 100 ) { $this->SetError('Receive data 0 bytes more than 100 times', __LINE__); return false; } } else { $length -= $bytes; } $buffer.=$cache; }while($length > 0); return true; } /** * 设置发送超时时间 * @param int $seconds 秒数,默认值为1 * @param int $microseconds 微秒,默认值为0 * * @return bool 发送成功返回true,否则返回false */ public function SetSendTimeout($seconds=1, $microseconds=0) { $seconds = intval($seconds);$microseconds = intval($microseconds); if( $seconds < 0 || $microseconds < 0 ) { $seconds = 1; $microseconds = 0; } if( !socket_set_option($this->rLink, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>$seconds, "usec"=>$microseconds)) ) { $this->SetSocketError(__LINE__); return false; } return true; } /** * 设置接收超时时间 * @param int $seconds 秒数,默认值为3 * @param int $microseconds 微秒,默认值为0 * * @return bool 发送成功返回true,否则返回false */ public function SetRecvTimeout($seconds=3, $microseconds=0) { $seconds = intval($seconds);$microseconds = intval($microseconds); if( $seconds < 0 || $microseconds < 0 ) { $seconds = 3; $microseconds = 0; } if( !socket_set_option($this->rLink, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$seconds, "usec"=>$microseconds)) ) { $this->SetSocketError(__LINE__); return false; } return true; } /** * 关闭连接的套接字 * * @return void */ protected function Close() { if( is_resource($this->rLink) ) { socket_close($this->rLink); $this->rLink = null; } } /** * 设置套接字错误 * @param int $line 错误行 * * @return void */ protected function SetSocketError($line) { $code = socket_last_error(); $msg = socket_strerror($code); $this->SetError("[$code]$msg", $line); } /** * 获取不定长数据 * @param string &$buffer 保存接收数据的缓存(注意:函数中会将此缓存清空后再存放接收到的数据) * @param int $flags 参数,默认为0 * * @return bool 发送成功返回true,否则返回false */ public function RecvForDontKnowLength(&$buffer, $flags=0) { $buffer = '';$bytes = -1;$cache = ''; do { if( $bytes > 0 ) { usleep(100); } $bytes = @socket_recv($this->rLink, $cache, 65535, $flags); if( false === $bytes ) { $this->SetSocketError(__LINE__); return false; } else if( $bytes < 65535 ) { $buffer.=$cache; break; } $buffer.=$cache; }while(true); return true; }}一个获取设备状态的例子,调用socket并获取数据/* * 设备注销 * */ private function DeviceLogout() { $serverIp = $_SERVER ['SERVER_ADDR']; // 服务器IP $header = "\x01\x00\x30\x04" . pack ( 'n', 0 ); $buffer = pack ( 'N', $this->deviceID ) . $serverIp . "\0"; $buffer = $header . pack ( 'n', 8 + strlen ( $buffer ) ) . $buffer; $this->package = $buffer; }/** * 发送数据包 * @param string $action socket发送动作:REGISTER_DEVICE、SENDCONFIG_DEVICE、GETDEVICE_INFORMATION、LOGOUT_DEVICE * @param string $ip ip地址 * * @return bytes 返回socket的数据 */ public function SendPackage($action = null,$ip=null,$lengthtype=null,$length=null) { $TCPv4 = new \X\Protocol\TCPv4 ( $ip, $this->agentPort ); $TCPv4->SetSendTimeout ( 5 ); $TCPv4->SetRecvTimeout ( 30 ); switch ($action) { case 'REGISTER_DEVICE' : $this->DeviceRegister(); break; case 'SENDCONFIG_DEVICE' : break; case 'GETDEVICE_INFORMATION' : $this->DeviceInformation (); break; case 'LOGOUT_DEVICE' : $this->DeviceLogout (); break; } $status = $TCPv4->Send ( $this->package ); $result = ''; if (0 === $lengthtype) // 定长 { $TCPv4->Recv ( $result, $length ); } else { $TCPv4->RecvForDontKnowLength ( $result ); } return $result; } public function RegisterDevice($ip=null) { /* * Action:注册行为: 1:检查设备是否注册于本Server; 2:注册该设备到本Server; 3:无视该设备已经注册于其他Server的情形,强制注册设备到本Server。 Result: 0:该设备成功注册于本Server; 1:注册失败; 2:该设备尚未注册; 3:该设备已在其他Server注册; 4:内部错误:该设备已在该Server注册,但指派的设备ID与现有的设备ID不同。 * */ $REG_TCP = new \X\Protocol\TCPv4 ( $ip, $this->agentPort ); $REG_TCP->SetSendTimeout ( 5 ); $REG_TCP->SetRecvTimeout ( 30 ); $this->DeviceRegister(); $status = $REG_TCP->Send ( $this->package ); $result = ''; $REG_TCP->Recv ( $result, 12 ); $SERVER_SOCKET_DATA = unpack ( 'N', substr ( $result, 8, 4 ) ); return $SERVER_SOCKET_DATA [1]; } 不得不说phpstorm 6的代码提示功能用户体验越来越强悍了.. (delphi) fastreport 里面有个TfrOLEExcelExport的控件是不是可以导出excel? 如何做内容摘要 FCK编辑器提交有样式的内容,影响整体的显示效果,望高手赐教! 一个简单的js 救助 急急急!! 问个php.ini配置问题 字符串处理的问题,欢迎高手进来指点。。 怎样让链接来提交链接所在的表单? 过来看看这个错误!!!!各位老大 怎么将一个页面链到404错误?还有怎么将一个页面的前进后退记录都删掉呢?(请版主不要删啊!) MediaWiki源码请教 关于preg_match_all的问题
/**
* TCP操作基类
* @package SHIT\Protocol
* @see \SHIT\Object
*/
class TCPv4 extends \X\Core\Object {
/**
* 套接字句柄
* @var resource
*/
protected $rLink = null;
/**
* 构造函数
* @param string $ip IP地址
* @param int $port 端口号
*
* @throws \X\Exception\Abstraction
*/
public function __construct($ip, $port) {
$this->rLink = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if( false === $this->rLink ) {
$this->rLink = null;
$this->SetSocketError(__LINE__);
throw new \X\Exception\Error($this->sError, $this->iErrno);
}
//设置连接超时为1秒
if( !$this->SetSendTimeout(1) ) {
$this->Close();
throw new \X\Exception\Error($this->sError, $this->iErrno);
}
// echo 'sssssssssssss';
if( !@socket_connect($this->rLink, $ip, $port) ) {
$this->SetSocketError(__LINE__);
$this->Close();
throw new \X\Exception\Error($this->sError, $this->iErrno);
}
// var_dump($this->rLink);exit;
if( !$this->SetSendTimeout(1) || !$this->SetRecvTimeout(3) ) {
$this->Close();
throw new \X\Exception\Error($this->sError, $this->iErrno);
}
}
/**
* 析构函数
*/
public function __destruct() {
$this->Close();
}
/**
* 发送数据
* @param string $buffer 待发送数据的缓存
* @param int $flags 参数,默认为0
*
* @return bool 发送成功返回true,否则返回false
*/
public function Send($buffer, $flags=0) {
$buffer = strval($buffer);
$bufLen = strlen($buffer);
if( $bufLen <= 0 ) {
return true;
}
$finishIndex = 0;
$bytes = null;$zeroTimes = 0;
do {
if( $finishIndex > 0 ) {
usleep(100);
}
$bytes = @socket_send($this->rLink, substr($buffer, $finishIndex), $bufLen - $finishIndex, $flags);
if( false === $bytes ) {
$this->SetSocketError(__LINE__);
return false;
} else if( $bytes <= 0 ) {
++$zeroTimes;
if( $zeroTimes > 100 ) {
$this->SetError('Send data 0 bytes more than 100 times', __LINE__);
return false;
}
} else {
$finishIndex += $bytes;
}
}while($finishIndex < $bufLen);
return true;
}
/**
* 获取数据
* @param string &$buffer 保存接收数据的缓存(注意:函数中会将此缓存清空后再存放接收到的数据)
* @param int $length 接收数据长度
* @param int $flags 参数,默认为0
*
* @return bool 发送成功返回true,否则返回false
*/
public function Recv(&$buffer, $length, $flags=0) {
$length = intval($length);
if( $length <= 0 ) {
return true;
}
$buffer = '';$bytes = -1;$cache = '';$zeroTimes = 0;
do {
if( $bytes > 0 ) {
usleep(100);
}
$bytes = @socket_recv($this->rLink, $cache, $length, $flags);
if( false === $bytes ) {
$this->SetSocketError(__LINE__);
return false;
} else if( $bytes <= 0 ) {
++$zeroTimes;
if( $zeroTimes > 100 ) {
$this->SetError('Receive data 0 bytes more than 100 times', __LINE__);
return false;
}
} else {
$length -= $bytes;
}
$buffer.=$cache;
}while($length > 0);
return true;
}
/**
* 设置发送超时时间
* @param int $seconds 秒数,默认值为1
* @param int $microseconds 微秒,默认值为0
*
* @return bool 发送成功返回true,否则返回false
*/
public function SetSendTimeout($seconds=1, $microseconds=0) {
$seconds = intval($seconds);$microseconds = intval($microseconds);
if( $seconds < 0 || $microseconds < 0 ) {
$seconds = 1;
$microseconds = 0;
}
if( !socket_set_option($this->rLink, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>$seconds, "usec"=>$microseconds)) ) {
$this->SetSocketError(__LINE__);
return false;
}
return true;
}
/**
* 设置接收超时时间
* @param int $seconds 秒数,默认值为3
* @param int $microseconds 微秒,默认值为0
*
* @return bool 发送成功返回true,否则返回false
*/
public function SetRecvTimeout($seconds=3, $microseconds=0) {
$seconds = intval($seconds);$microseconds = intval($microseconds);
if( $seconds < 0 || $microseconds < 0 ) {
$seconds = 3;
$microseconds = 0;
}
if( !socket_set_option($this->rLink, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$seconds, "usec"=>$microseconds)) ) {
$this->SetSocketError(__LINE__);
return false;
}
return true;
}
/**
* 关闭连接的套接字
*
* @return void
*/
protected function Close() {
if( is_resource($this->rLink) ) {
socket_close($this->rLink);
$this->rLink = null;
}
}
/**
* 设置套接字错误
* @param int $line 错误行
*
* @return void
*/
protected function SetSocketError($line) {
$code = socket_last_error();
$msg = socket_strerror($code);
$this->SetError("[$code]$msg", $line);
}
/**
* 获取不定长数据
* @param string &$buffer 保存接收数据的缓存(注意:函数中会将此缓存清空后再存放接收到的数据)
* @param int $flags 参数,默认为0
*
* @return bool 发送成功返回true,否则返回false
*/
public function RecvForDontKnowLength(&$buffer, $flags=0) {
$buffer = '';$bytes = -1;$cache = '';
do {
if( $bytes > 0 ) {
usleep(100);
}
$bytes = @socket_recv($this->rLink, $cache, 65535, $flags);
if( false === $bytes ) {
$this->SetSocketError(__LINE__);
return false;
} else if( $bytes < 65535 ) {
$buffer.=$cache;
break;
}
$buffer.=$cache;
}while(true);
return true;
}
}一个获取设备状态的例子,调用socket并获取数据/*
* 设备注销
* */
private function DeviceLogout()
{
$serverIp = $_SERVER ['SERVER_ADDR']; // 服务器IP
$header = "\x01\x00\x30\x04" . pack ( 'n', 0 );
$buffer = pack ( 'N', $this->deviceID ) . $serverIp . "\0";
$buffer = $header . pack ( 'n', 8 + strlen ( $buffer ) ) . $buffer;
$this->package = $buffer;
}/**
* 发送数据包
* @param string $action socket发送动作:REGISTER_DEVICE、SENDCONFIG_DEVICE、GETDEVICE_INFORMATION、LOGOUT_DEVICE
* @param string $ip ip地址
*
* @return bytes 返回socket的数据
*/
public function SendPackage($action = null,$ip=null,$lengthtype=null,$length=null) {
$TCPv4 = new \X\Protocol\TCPv4 ( $ip, $this->agentPort );
$TCPv4->SetSendTimeout ( 5 );
$TCPv4->SetRecvTimeout ( 30 );
switch ($action) {
case 'REGISTER_DEVICE' :
$this->DeviceRegister();
break;
case 'SENDCONFIG_DEVICE' :
break;
case 'GETDEVICE_INFORMATION' :
$this->DeviceInformation ();
break;
case 'LOGOUT_DEVICE' :
$this->DeviceLogout ();
break;
}
$status = $TCPv4->Send ( $this->package );
$result = '';
if (0 === $lengthtype) // 定长
{
$TCPv4->Recv ( $result, $length );
} else {
$TCPv4->RecvForDontKnowLength ( $result );
}
return $result;
}
public function RegisterDevice($ip=null)
{
/*
* Action:注册行为:
1:检查设备是否注册于本Server;
2:注册该设备到本Server;
3:无视该设备已经注册于其他Server的情形,强制注册设备到本Server。
Result:
0:该设备成功注册于本Server;
1:注册失败;
2:该设备尚未注册;
3:该设备已在其他Server注册;
4:内部错误:该设备已在该Server注册,但指派的设备ID与现有的设备ID不同。 * */
$REG_TCP = new \X\Protocol\TCPv4 ( $ip, $this->agentPort );
$REG_TCP->SetSendTimeout ( 5 );
$REG_TCP->SetRecvTimeout ( 30 );
$this->DeviceRegister();
$status = $REG_TCP->Send ( $this->package );
$result = '';
$REG_TCP->Recv ( $result, 12 );
$SERVER_SOCKET_DATA = unpack ( 'N', substr ( $result, 8, 4 ) );
return $SERVER_SOCKET_DATA [1];
}