后台运行:
nohup php -q /var/www/html/modules/sag_manager/pnpserver/pnpserver.php > /var/pnp/pnpserver.log
<?php
error_reporting (7);
set_time_limit (0);
ob_implicit_flush ();
define("UDP_PORT",7001);
define("TCP_PORT",7002);
require_once ("sock.inc");
require_once ("bridge_message.class.php");
/*============================================================================*/
消息处理 函数 00 0c 29 2b 7c 2d
/*============================================================================*/
function sagmes_to_str($buf)
{
//echo strlen($buf);
$pre='';
for($i=0; $i<6; $i++){
$pre.= bin2hex($buf[$i]);
}
$meslen=hexdec(substr($pre,2,8));
$bac=substr($buf,6);
$buf=$pre.$bac;
return $buf;
}
function Getmeshead($mes){
$meshead=trim(strtolower(substr($mes,0,2)));
return $meshead;
}
function Getmeslen($mes){
$meslen=trim(substr($mes,2,8));
return hexdec($meslen); // 原来的偏?相当二进制存?
}
function Getmestype($mes){
$mestype=trim(substr($mes,10,2));
return $mestype;
}
function Getmescontent($mes){
$mescontent=trim(substr($mes,12));
$macarr=explode(":", $mescontent);
if(count($macarr)){
$mescontent='';
foreach($macarr as $value)
$mescontent.=$value;
}
return trim($mescontent);
}
function mescontent_str_to_int($content){
$sendstr = $content{3}.(($content{2}) << 8).(($content{1}) << 16).(($content{0}) << 24);
}
function pnp_to_sag_mes($type,$content=''){
GLOBAL $file_len;
$len=strlen($content); //加(0x7e+消息长度+消息类型?6 + '/0' 最后发???
$s1=intval(($len & 0xff000000) >> 24); //取整?
$s2=intval(($len & 0x00ff0000) >> 16);
$s3=intval(($len & 0x0000ff00) >> 8);
$s4=intval($len & 0x000000ff);
//echo "s4:$s4 /n"."s3:$s3 /n"."s2:$s2 /n"."s1:$s1 /n"."len:$len /n";
if($len==0)
$frm_str=chr(0x7e).chr(0x0).chr(0x0).chr(0x0).chr(0x0).chr($type);
else
$frm_str=chr(0x7e).chr($s4).chr($s3).chr($s2).chr($s1).chr($type).$content;
unset($file_len);
return $frm_str;
}
/************************ $sockhandle˵********************************
****udp ?udp $socket $socket = new socke("UDP","AF_INET");**********
****udp ?tcp $TCPsocket $TCPsocket = new socke(); ******************
****mac Ӧmacַ ip Ӧip ַ*************************************
**** sock.incд
*****************************************************************************/
function get_xlm($mac){
$path_xml = "/var/www/html/modules/sag_manager/data/base/";
$filexml=$path_xml.strtoupper($mac).".xml";
GLOBAL $file_len;
$file_len=0;
$content="";
if(is_file($filexml)){
$content=file_get_contents($filexml);
$file_len=filesize($filexml);
}
return $content;
}
/*============================================================================*/
Create 数据库链接 主要是提供链接状态
/*============================================================================*/
GLOBAL $link,$db;
$link="";
function update_state($mac,$connstate='',$ip='',$portstatus='',$truckstatus=''){
if($link==""){
$dbhost = "localhost";
$dbuser = "root";
$dbname="asterisk";
$dbpass = "eLaStIx.2oo7";
$link = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die("Could not connect: " . mysql_error());
$db=mysql_select_db($dbname, $link);
}
if(trim($portstatus)!='' && $ip!=""){
$sql=" update macgroup set connstate=".$connstate.", ip='".$ip."' , portstatus='".$portstatus."' where mac= '".$mac."'";
mysql_query($sql);
}
if($ip!="" && trim($portstatus)==''){
$sql=" update macgroup set connstate=".$connstate.", ip='".$ip."' where mac= '".$mac."'";
mysql_query($sql);
}
//echo $sql;
if($connstate=="" && $portstatus=='' && $ip==''){
$sql=" update macgroup set connstate=0 ,ip='' where mac= '".$mac."'";
mysql_query($sql);
}
}
/*============================================================================*/
socket事务处理函数 即协议内?
/*============================================================================*/
function interact($mysock, $data){
GLOBAL $TCPsocket,$update_data,$shm, $need_reboot_mac, $need_update_macname;
$update_remark="";
$message= sagmes_to_str($data);
$meshead=Getmeshead($message);
$mestype=Getmestype($message);
$mescontent=Getmescontent($message);
$Clientip=@$TCPsocket->socketinfo[$mysock]["ip"];
$single_mac= $shm->get_msg(237);
if(trim($single_mac)!=""){
foreach($TCPsocket->socketinfo as $key=>$value){
#print_r($value);
if(trim(strtoupper($single_mac))==trim(strtoupper($value["mac"]))){
$need_update_macname[$key]= strtoupper($single_mac);
echo "pnp have recived ip: ".$value["ip"]." of single to update, and it's mac is".$single_mac ."/n";
break;
}
}
}
#print_r($TCPsocket->socketinfo);
#echo "need_update_macname:/n/n";
#print_r($need_update_macname); echo "/n/n";
$rebootmac = $shm->get_msg(238);
if(trim($rebootmac)!=""){
foreach($TCPsocket->socketinfo as $key=>$value){
if(trim(strtoupper($rebootmac))==trim(strtoupper($value["mac"]))){
$need_reboot_mac[$key]=strtoupper($rebootmac);
echo "pnp have recived ip: ".$value["ip"]." of single to reboot,and it's mac is".$rebootmac ."/n";
break;
}
}
}
$key='';
if(isset($TCPsocket->socketinfo[$mysock]['mac'])){
$key=@array_search($TCPsocket->socketinfo[$mysock]['mac'],$need_update_macname);
$update_remark = ($key!='')? "yes" :"no";
update_state(($TCPsocket->socketinfo[$key]['mac']),1,@$TCPsocket->socketinfo[$key]["ip"]);
}else {
$update_remark="no";
}
if((Getmeshead($message)=='7e' && Getmestype($message)=='05') || $update_remark == "yes" || trim($single_mac)!="") {
//数据有更新
if($update_remark=="yes"){
$Mac=$TCPsocket->socketinfo[$mysock]['mac'];
#echo "/n/n/n/n/n/n";
echo " The PNP server prepare to synchro date of ".$TCPsocket->socketinfo[$mysock]['ip'] ."/n";
#echo "/n/n/n/n/n/n";
//substr($update_file,0,12);
}else{ //初次加载数据
$mescontent=Getmescontent($message);
echo " The PNP server have received message :".$mescontent." from $Clientip /n";
$Mac=substr($mescontent,0,12);
}
$TCPsocket->set_client_mac($mysock,strtoupper($Mac));
$mescnt=get_xlm($Mac);
if($mescnt!=""){
$sendmesg=Pnp_to_sag_mes(0x04,$mescnt);
}else{
$sendmesg=Pnp_to_sag_mes(0x06); //没有找到 发送06消息
$update_data="no";
}
$buf=substr($sendmesg,0,6); //本段调试
$pre=null;
for($i=0; $i<6; $i++){
$pre.= bin2hex($buf[$i]);
}
$len=strlen($sendmesg);
write_me($mysock, $sendmesg);
//已经更新的mac删除
if($update_remark=="yes"){
$TCPsocket->set_client_mac($mysock,strtoupper($need_update_macname[$key]));
unset($need_update_macname[$key]);
}
return;
}
$key="";
if(isset($TCPsocket->socketinfo[$mysock]['mac'])){
$key=@array_search(trim($TCPsocket->socketinfo[$mysock]['mac']),$need_reboot_mac); //0x0a PnP服务器要求SAG重新启动
//print_r($need_reboot_mac);
if($key!= FALSE || $key!= ""){
$sendmesg=Pnp_to_sag_mes(0x0a);
write_me($mysock,$sendmesg);
echo " The PNP server have sent to client the message of reboot!";
$TCPsocket->set_client_mac($mysock,strtoupper($need_reboot_mac[$key]));
unset($need_reboot_mac[$key]);
return;
}
}
If(Getmeshead($message)=='7e' && Getmestype($message)=='07') {
$Mescontent=Getmescontent($message);
Echo " The PNP server have received 07 of message :".$message." From $Clientip ! /n";
return;
}
If(Getmeshead($message)=='7e' && Getmestype($message)=='09') {
$Mescontent=Getmescontent($message);
Echo " The PNP server have received 09 of message :".$message." From $Clientip /n";
Echo " And the client have loaded data From PNP server /n";
return;
}
If(Getmeshead($message)=='7e' && Getmestype($message)=='0d'){
//$Mescontent=Getmescontent($message);
$Mescontent=null;
for($i=6; $i<39; $i++){
$Mescontent.= bin2hex($data[$i]);
}
$portstatus=$Mescontent;
update_state(($TCPsocket->socketinfo[$mysock]['mac']),1,@$TCPsocket->socketinfo[$mysock]["ip"],$portstatus);
Echo " The PNP server have received chanel state :".$Mescontent." From $Clientip /n";
Echo " The PNP server have received chanel message :".$message." From $Clientip /n";
return;
}
//心跳处理
If(Getmeshead($message)=='7e' && Getmestype($message)=='0b'){
$Mescontent=Getmescontent($message);
Echo " The PNP server have received 0b of message :".$message." From $Clientip /n";
Echo " The PNP server is answering beaten from the client of $Clientip /n";
$sendmesg=Pnp_to_sag_mes(0x08);
write_me($mysock,$sendmesg);
#update_state(($TCPsocket->socketinfo[$mysock]['mac']),1,@$TCPsocket->socketinfo[$mysock]["ip"]);
return;
}
return;
}
function write_me($mysock, $message){
GLOBAL $TCPsocket;
$TCPsocket->write($mysock,"$message");
return;
}
function login ($mysock){
GLOBAL $TCPsocket;
return;
}
function logout ($sock, $message = "" ){
GLOBAL $TCPsocket;
echo " The ".$TCPsocket->socketinfo[$sock]['ip']." of clients have disconnected! /n";
if($TCPsocket->socketinfo[$sock]['mac']!="")
update_state($TCPsocket->socketinfo[$sock]['mac'],'','','','');
$TCPsocket->close($sock);
unset($sock);
unset($TCPsocket->socketinfo[$sock]);
return;
}
function shutdown (){
GLOBAL $TCPsocket;
GLOBAL $socket;
$socket->close();
$TCPsocket->close();
exit;
}
function reboot_sag($mysock,$key){
$sendmesg=Pnp_to_sag_mes(0x0a);
echo " The PNP server reqiure the client to reboot!";
write_me($mysock,$sendmesg);
unset($need_reboot_mac[$key]);
return;
}
function udpshutdown ($message = "The PNP server goes shutdown now" ){
GLOBAL $socket;
$socket->close();
exit;
}
/*============================================================================*/
提供web页面调用的函口 后来没有用到此处函数 不能够实时用信号解决此种应用
/*============================================================================*/
//提供给有数据更新时的接口 $update_data==yes 是有数据更新
function set_updataxml($isupdate){
GLOBAL $isupdate;
$update_data=$isupdate;
}
//设置重新启动sag $isrebootsag=="yes" 重新启动sag
function set_reboot_sag($sag_reset){
GLOBAL $isrebootsag;
$isrebootsag=$sag_reset;
}
/*============================================================================*/
Create udp Socket
/*============================================================================*/
GLOBAL $socket;
$socket=null;
//通过信号传过来的
GLOBAL $shm,$have_update_macname,$need_update_macname;
$shm = new Bright_Message();
$need_update_macname=array();
GLOBAL $need_reboot_mac;
$need_reboot_mac=array();
$update_file="";//更新的数据文件名?外部传入
GLOBAL $portstatus; //端口状态字符串 32
$portstatus="";
GLOBAL $TCPsocket;
$TCPsocket=null;
$io=null;
$arrip=array(); //客户端ip数组
$data=null;
$accept_socket=array();
@exec("ifconfig | awk '/inet/{print $3}' | awk -F: '{print $2}'|grep '....255' ",$broadarr);
$broadaddr=$broadarr[0];
$socket = new socke("UDP","AF_INET");
$socket->bind($broadaddr, UDP_PORT);
$socket->enable_broadcast();
$socket->block($socket->Socket,false);
$TCPsocket = new socke(); //var_dump($TCPsocket->Socket);
@exec(" ifconfig | awk '/inet/{print $2}' | awk -F: '{print $2}'|grep '192' ",$iparr);
$localipaddr = $iparr[0];
$TCPsocket->block($TCPsocket->Socket,false);
if(!$io=$TCPsocket->listen("$localipaddr",TCP_PORT)){
echo" error:tcp socket listeninf failure";
}
shell_exec("chmod 777 -R /var/www/html/modules/sag_manager/data/base");
shell_exec("chown root -R /var/www/html/modules/sag_manager/data/base");
do{
flush();
if($TCPsocket!=null && count($TCPsocket->socketinfo) >0 ){
$now_time=time();
foreach($TCPsocket->socketinfo as $key=> $value){
if(count($value) < 3)
continue;
$now_time = time();
$repos_time = $now_time-$value['last'] ;
if($repos_time>120) #大于两分钟 没有反映 视客户端已经断开链接
logout($key);
}
}
if(count($socket->socketinfo)==0){
echo " The PNP server is waiting for connections from clients! /n";
usleep(500);
}
if($TCPsocket!=null && $io!=null){
if (connection_status()!=0){
$socket->close();
die;
}
usleep(1000);
foreach($TCPsocket->can_read() as $sock){
if($io == $sock){
$accept_socket[]=$TCPsocket->accept();
login($mysock);
}else{
if($sock!=$TCPsocket->Socket && in_array($sock,$accept_socket)){
$data = $TCPsocket->binary_read($sock);
}else{
continue;
}
if($data === false && in_array($sock,$accept_socket)){
logout($sock,"Connection reset by Beer");
continue;
}
interact($sock, $data);
}
}
}
//udp链接处理
$udp_return = $socket->recv($socket->Socket,1024);
if(($udp_return)==false)
continue;
$udp_return[0]=sagmes_to_str($udp_return[0]);
$message=$udp_return[0];
$clientip=$udp_return[1];
$clientport=$udp_return[2];
if(Getmeshead($message)=='7e' && Getmestype($message)=='01') {
echo " The PNP server have received broadcast of message :".Getmescontent($message)." from $clientip /n";
//socket_iovec_alloc();
$msg = pnp_to_sag_mes(0x02);
$len=strlen($msg);
$fileName=strtoupper(Getmescontent($message));
if(!is_file("/var/www/html/modules/sag_manager/data/base/".$fileName.".xml"))
continue;
$socket->send($socket->Socket,$msg,$clientip,$clientport);
if($TCPsocket==null){
//Create tcp Socket
$TCPsocket = new socke(); //var_dump($TCPsocket->Socket);
@exec(" ifconfig | awk '/inet/{print $2}' | awk -F: '{print $2}'|grep '192' ",$iparr);
$localipaddr = $iparr[0];
$TCPsocket->block($TCPsocket->Socket,false);
if(!$io=$TCPsocket->listen("$localipaddr",TCP_PORT)){
echo" error:tcp socket listeninf failure";
}
}
continue;
}
}while(1);
?>
<?
class socke {
var $opener;
/* Opener = bool
Makes the lineberak in debug
If we have getenv[SCRIPT_NAME] we are www and will use <br> else /n
Set in constructor
*/
var $Socket;
/*Created Socket
TCP, UDP
AF_INET, AF_UNIX
*/
var $clients;
/* Clients
Array of Socketdeskriptors
[++][ResourceID]
*/
var $socketinfo;
/*Socketinfo
Array of additional informations
Always set by default are:
[ResourceID][IP] == IP of remote host. IF AF_UNIX the path
[ResourceID][Host] == Hostname of remote host. IF AF_UNIX the path
[ResourceID][started] == Timestamp first connect
[ResourceID][last] == Timestamp last action
[ResourceID][anyuservalues] can set by method set_socketinfo($deskriptor,$field,$value)
lyj加 [ResourceID][mac]
*/
var $protocol;
/* protocol array
Set by set_protocol(); Default is TCP
[tag] = TCP / UDP
[type] = SOCK_DGRAM / SOCK_STREAM
[proto] = SOL_TCP / SOL_TCP
*/
var $family;
/* Family string
Set by set_family(); Default is "AF_INET"
AF_INET / AF_UNIX
*/
var $myhost;
/* myhost = string
Current adress IP/HOST we listen at AF_INET sockets
else Location/Name of the socketfile for AF_UNIX sockets (relative unixpath)
*/
var $myport;
/* myport = integer
Current port we listen at AF_INET sockets
else 0 at AF_UNIX
*/
var $method;
/* Method string
pointer incl. last called method_name
*/
function socke ($proto = "TCP", $family = "AF_INET") {
$this->method = "socke";
//Ini Vars
$this->opener = FALSE;
$this->clients = ARRAY();
$this->socketinfo = ARRAY();
$this->protocol = ARRAY();
if (getenv("SCRIPT_NAME")){
$this->opener = TRUE;
}
//Set defaults
$this->set_protocol($proto);
$this->set_family($family);
$this->create_normal_sock();
return true;
}
function create_normal_sock(){
$this->method = "create_normal_sock";
switch($this->family){
case AF_UNIX:
if (($this->Socket = socket_create(AF_UNIX, SOCK_STREAM, 0)) < 0 ){
$this->error($this->Socket,"socket_create() failed !/n",1);
//exitpoint
}
break;
default:
if (($this->Socket = socket_create($this->family, $this->protocol['type'], $this->protocol['proto'])) < 0 ){
$this->error($this->Socket,"socket_create() failed !/n",1);
//exitpoint
}
}
socket_clear_error($this->Socket);
return True;
}
function set_protocol($proto = "TCP"){
$this->method = "set_protocol";
$proto = strtoupper($proto);
switch($proto){
case "TCP":
$this->protocol['tag'] = "TCP";
$this->protocol['type'] = SOCK_STREAM;
$this->protocol['proto'] = SOL_TCP;
break;
case "UDP":
$this->protocol['tag'] = "UDP";
$this->protocol['type'] = SOCK_DGRAM;
$this->protocol['proto'] = SOL_UDP;
break;
default:
$this->error("","Protocol /"$proto/" is not a valid Socket-protocol-type!/nUse TCP/UPD Quit../n",1);
//exitpoint
}
return True;
}
function set_family($family = "AF_INET"){
$this->method = "set_family";
$family = strtoupper($family);
switch($family){
case "AF_INET":
$this->family = AF_INET;
break;
case "AF_UNIX":
$this->family = AF_UNIX;
break;
default:
$this->error("","Type /"$family/" is not a valid Socket-family!/nUse AF_INET/AF_UNIX Quit../n",1);
//exitpoint
}
return True;
}
function accept() {
$this->method = "accept";
if (!($conn_id = socket_accept($this->Socket))){
$this->Error($this->Socket,"failed !/n");
}else{
$this->add_socket($conn_id);
return $conn_id;
}
}
function set_option($level,$option,$value){
$this->method = "set_option";
if (!socket_set_option($this->Socket, $level, $option, $value)) {
$this->Error($this->Socket,"Values: ($level,$option,$value) failed !/n");
}
}
function bind ($adress_or_path = "0.0.0.0" , $port){
$this->method = "bind";
if(!$adress_or_path){$adress_or_path = "0.0.0.0";}
if($this->family == "AF_UNIX"){
$port = 0;
$sockfile = "/tmp/D2Dsock_".getmypid().".sock";
if($adress_or_path == "0.0.0.0"){
$adress_or_path = $sockfile;
if(!$this->isdir("/tmp")){
$this->error("","Cant not use default path /"/tmp//" to create socketfile !/nDirectory does not exists/nUse bind() with existing path",1);
//exitpoint
}
}
$pathparts = pathinfo($adress_or_path);
if(!$pathparts['extension'] || !$pathparts['basename']){
$this->error("","/"$adress_or_path/" is no valid filename! Useage /path/name.extension /n",1);
//exitpoint
}
if(!$this->isdir($pathparts[dirname])){
$this->error("","Cant not use path /"$pathparts[dirname]/" to create socketfile ! Directory does not exists/n",1);
//exitpoint
}
if(file_exists($adress_or_path)){
$this->error("","Socketfile already exists: /"$adress_or_path/"! Delete, if the socket is not in use anymore/n",1);
//exitpoint
}
if(!$fp = @fopen($adress_or_path,"w+")){
$this->error("","Cant create socketfile in: /"$adress_or_path/"! Make sure we have permissions to do this/n",1);
//exitpoint;
}else{
fclose($fp);
unlink($adress_or_path);
}
}
//echo $adress_or_path;
if (!socket_bind($this->Socket, $adress_or_path, $port)) {
$this->error($this->Socket,"Values: ($adress_or_path, $port) failed !/n",1);
//exitpoint
}
$this->myhost = $adress_or_path;
$this->myport = $port;
return True;
}
function listen ($adress_or_path = "0.0.0.0", $port){
$this->method = "listen";
$this->set_option(SOL_SOCKET, SO_REUSEADDR, 1);
$this->bind($adress_or_path, $port);
if (($ret = socket_listen($this->Socket,15)) < 0 ) {
$this->error($this->Socket,"Values: ($adress_or_path,$port) failed !/n",1);
//exitpoint
}
$this->add_socket($this->Socket);
return $this->Socket;
}
function block($deskriptor=null, $block = true) {
$this->method = "block";
if(!$deskriptor){
$deskriptor = $this->Socket;
}
if(!$block){
if(!socket_set_nonblock($deskriptor)){
$this->Error($deskriptor,"NoneBlock failed !/n");
return False;
}
}else {
if(!socket_set_block($deskriptor)){
$this->Error($deskriptor,"Block failed !/n");
return False;
}
}
return True;
}
function can_read() {
$this->method = "can_read";
$read = $this->clients;
//һѡִеsocket
if(false === socket_select($read, $write = NULL, $set_e = NULL, 0, 0)){
$this->Error("","Socket_select() failed !/n");
$read = Array();
}
return $read;
}
function can_write() {
$this->method = "can_write";
$write = $this->clients;
if( false === socket_select($read, $write = NULL, $set_e = NULL, 0, 0)){
$this->Error("","Socket_select() failed !/n");
$write = Array();
}
return $write;
}
function write($deskriptor, $string = "/x0", $incl_mypipe = FALSE) {
$this->method = "write";
if($deskriptor == $this->Socket && !$incl_mypipe){
//dont wirte into my own pipe -> gives error broken pipe
//Dunno if this will be needed anytime ? then set to true
return;
}
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if($res = socket_write($deskriptor, $string) ){
$this->socketinfo[$deskriptor]['last'] = time();
return $res;
}
$this->error($deskriptor);
return false;
}
function send($deskriptor,$string, $host, $port = null) {
$this->method = "send";
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
// Send a packet when using UDP.
if(socket_sendto($deskriptor, $string, strlen($string), 0, gethostbyname($host), $port)){
$this->socketinfo[$deskriptor]['last'] = time();
return true;
}
$this->error($deskriptor,"Host: /"$host/", Port: /"$port/" failed !/n");
return false;
}
function recv($deskriptor, $len) {
$this->method = "recv";
// Recieve from a socket when using UDP.
$buf = null;
$host = null;
$port = null;
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
// var_dump($deskriptor);
//MSG_WAITALL
//if(@socket_recvfrom($deskriptor, $buf, $len, 0, $host, $port)){
if(@socket_recvfrom($deskriptor, $buf, $len, MSG_WAITALL, $host, $port)){
$this->socketinfo[$deskriptor]['last'] = time();
return array($buf, $host, $port);
}
//$this->error($deskriptor);
return false;
}
function binary_read($deskriptor, $length = 1024) {
$this->method = "binary_read";
// Reads $length number of bytes without stopping at /n or /r.
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if (FALSE === ($buf = socket_read ($deskriptor, $length, PHP_BINARY_READ))) {
$this->error($deskriptor);
}
$this->socketinfo[$deskriptor]['last'] = time();
return $buf;
}
function read($deskriptor, $length = 1024) {
$this->method = "read";
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
$read = "";
if (($read = socket_read($deskriptor, $length, PHP_NORMAL_READ)) === false) {
if ($read != ''){
$this->error($deskriptor);
} else {
if($deskriptor!=$this->Socket)
$this->close($deskriptor);
return FALSE;
}
} else {
$this->socketinfo[$deskriptor]['last'] = time();
$read = str_replace("/r", '', $read);
$read = str_replace("/n", '', $read);
if($read){return $read;}
return NULL;
}
}
function shutdown($deskriptor=null, $how = "ALL") {
$this->method = "shutdown";
switch(strtoupper($how)){
case "ALL":
$how = 2;
break;
case "READ":
$how = 0;
break;
case "WRITE":
$how = 1;
break;
default:
$this->error("","Socket Shutdown /"$how/" is not valid !/nUse ALL/READ/WRITE");
return False;
}
if(!$deskriptor){
$deskriptor = $this->Socket;
}
if (socket_shutdown($deskriptor, $how)<0){
$this->error($deskriptor);
}
return true;
}
function close($deskriptor=null) {
$this->method = "close";
if(!$deskriptor){
//Shutdown ALL incl. Me
while (list ($id, $sock) = each ($this->clients)) {
if($sock != $this->Socket){
socket_close($sock);
}
}
if($this->family == AF_UNIX && file_exists($this->myhost)){
unlink($this->myhost);
}
socket_close($this->Socket);
$this->clients = "";
$this->socketinfo = "";
$this->Socket = "";
return True;
}
$this->remove_socket($deskriptor);
socket_close($deskriptor);
return True;
}
function add_socket ($socket){
$this->method = "add_socket";
$this->clients[] = $socket;
if($socket != $this->Socket){
$ip = $this->get_ip($socket);
$this->socketinfo[$socket]['ip'] = $ip;
$this->socketinfo[$socket]['host'] = $this->get_host($ip);
} else {
//its me ...
// $this->socketinfo[$socket]['ip'] = $this->myhost;
// $this->socketinfo[$socket]['host'] = "not supported";
}
$this->socketinfo[$socket]['started'] = time();
$this->socketinfo[$socket]['last'] = time();
}
function remove_socket($deskriptor){
$this->method = "remove_socket";
$sockets = ARRAY();
reset($this->clients);
foreach($this->clients as $sock) {
if($deskriptor != $sock){
$sockets[] = $sock;
}
}
$this->remove_socketinfo($deskriptor);
$this->clients = $sockets;
}
function get_socketinfo($deskriptor="", $field = ""){
$this->method = "get_socketinfo";
if(!$deskriptor){
return $this->socketinfo;
}
if(!$this->socketinfo[$deskriptor]){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if($field){
return $this->socketinfo[$deskriptor][$field];
}
return $this->socketinfo[$deskriptor];
}
function set_socketinfo($deskriptor, $field, $value){
$this->method = "set_socketinfo";
if(in_array($field,array("ip","host","started","last"))){
$this->Error("","Field /"$field/" is already in use by system/n");
return False;
}
$this->socketinfo[$deskriptor][$field] = $value;
return True;
}
function remove_socketinfo($deskriptor){
$this->method = "remove_socketinfo";
$infos = ARRAY();
$this->socketinfo[$deskriptor] = "";
reset($this->socketinfo);
while (list ($id, $sock) = each ($this->socketinfo)) {
if($sock){
$infos[$id] = $sock;
}
}
$this->socketinfo = $infos;
}
function get_host($ip){
$this->method = "get_host";
if($this->family == AF_INET ){
if(!$ip){
$this->Error("","Not a valid IP /"$ip/" given");
return false;
}
return gethostbyaddr($ip);
}
return "localhost";
}
function get_ip ($deskriptor){
$this->method = "get_ip";
if($this->family == AF_INET ){
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
socket_getpeername($deskriptor, &$addr);
if(!$addr){
return false;
}
return $addr;
}
return $this->mypath;
}
function debug_print($message){
if($this->opener){
echo nl2br($message);
return;
}
echo "$message";
return;
}
function isdir($directory){
return ((@fileperms("$directory") & 0x4000) == 0x4000);
}
function Error($deskriptor="", $message = "", $critical = FALSE) {
$headline = "Error in :".__CLASS__."::".$this->method."()";
if(!$critical){
if($message){$headline = "$headline/n->$message";}
if($deskriptor){$headline.= "/n->".@socket_strerror(socket_last_error($deskriptor));}
$this->debug_print("$headline/n");
return;
}
$msg = "Socketstatus below:/n";
$msg.= 'Last deskriptor status: '.@socket_strerror(socket_last_error($deskriptor))."/n";
$msg.= 'Last socket status: '.@socket_strerror(socket_last_error($this->Socket))."/n";
$msg.= "AT: ".__LINE__ ."/nIn:". __FILE__;
$this->debug_print("CRITICAL ERROR !/n$headline/n$message/n$msg/nSocke dying....");
exit();
}
function enable_broadcast() {
//SO_BROADCAST = $00020;
if(($ret = socket_set_option($this->Socket, SOL_SOCKET, SO_BROADCAST, 1)) < 0) {
$this->error("Failed to enable broadcast option.");
}
}
function disable_broadcast() {
if(($ret = socket_set_option($this->Socket, SOL_SOCKET, SO_BROADCAST, 0)) < 0) {
$this->error("Failed to disable broadcast option.");
}
}
}
?>
<?
//ipcs –am命令可以查看share memory的状况
send.php: 发送使用
/*include "bridge_message.class.php";
$shm = new Bright_Message();
$shm->snd_msg(2,'this is my simple message');
///receive.php: 收到使用
include "bridge_message.class.php";
$shm = new Bright_Message();
$msg = get_msg(2);
echo print_r($msg,1);
*/
class Bright_Message
{
var $bright;
var $SHM_KEY;
var $my_pid;
function Bright_Message($SHM_KEY=null)
{
$this->my_pid = getmypid();//Get own pid
if (is_null($SHM_KEY)) $this->SHM_KEY = '123123123';
$this->bright = shm_attach($this->SHM_KEY, 1024, 0666);
$this->one_instance();
}
function get_msg($id,$remove=true)
{
if(@$msg=shm_get_var($this->bright,$id))
{
if ($remove) @shm_remove_var($this->bright,$id);
return $msg;
} else return false;
}
function snd_msg($id,$msg)
{
@shm_put_var($this->bright,$id,$msg);
return true;
}
function one_instance()
{
$SHM_PID = $this->get_msg(1,false);
if((strpos(exec('ps p'.$SHM_PID),$_SERVER['SCRIPT_FILENAME'])) === false)
$this->snd_msg(1,$this->my_pid); else
{
echo "This program exists on pid: $SHM_PID/r/n/r/n";
exit;
}
}
}
<?
class socke {
var $opener;
/* Opener = bool
Makes the lineberak in debug
If we have getenv[SCRIPT_NAME] we are www and will use <br> else /n
Set in constructor
*/
var $Socket;
/*Created Socket
TCP, UDP
AF_INET, AF_UNIX
*/
var $clients;
/* Clients
Array of Socketdeskriptors
[++][ResourceID]
*/
var $socketinfo;
/*Socketinfo
Array of additional informations
Always set by default are:
[ResourceID][IP] == IP of remote host. IF AF_UNIX the path
[ResourceID][Host] == Hostname of remote host. IF AF_UNIX the path
[ResourceID][started] == Timestamp first connect
[ResourceID][last] == Timestamp last action
[ResourceID][anyuservalues] can set by method set_socketinfo($deskriptor,$field,$value)
lyj加 [ResourceID][mac]
*/
var $protocol;
/* protocol array
Set by set_protocol(); Default is TCP
[tag] = TCP / UDP
[type] = SOCK_DGRAM / SOCK_STREAM
[proto] = SOL_TCP / SOL_TCP
*/
var $family;
/* Family string
Set by set_family(); Default is "AF_INET"
AF_INET / AF_UNIX
*/
var $myhost;
/* myhost = string
Current adress IP/HOST we listen at AF_INET sockets
else Location/Name of the socketfile for AF_UNIX sockets (relative unixpath)
*/
var $myport;
/* myport = integer
Current port we listen at AF_INET sockets
else 0 at AF_UNIX
*/
var $method;
/* Method string
pointer incl. last called method_name
*/
function socke ($proto = "TCP", $family = "AF_INET") {
$this->method = "socke";
//Ini Vars
$this->opener = FALSE;
$this->clients = ARRAY();
$this->socketinfo = ARRAY();
$this->protocol = ARRAY();
if (getenv("SCRIPT_NAME")){
$this->opener = TRUE;
}
//Set defaults
$this->set_protocol($proto);
$this->set_family($family);
$this->create_normal_sock();
return true;
}
function create_normal_sock(){
$this->method = "create_normal_sock";
switch($this->family){
case AF_UNIX:
if (($this->Socket = socket_create(AF_UNIX, SOCK_STREAM, 0)) < 0 ){
$this->error($this->Socket,"socket_create() failed !/n",1);
//exitpoint
}
break;
default:
if (($this->Socket = socket_create($this->family, $this->protocol['type'], $this->protocol['proto'])) < 0 ){
$this->error($this->Socket,"socket_create() failed !/n",1);
//exitpoint
}
}
socket_clear_error($this->Socket);
return True;
}
function set_protocol($proto = "TCP"){
$this->method = "set_protocol";
$proto = strtoupper($proto);
switch($proto){
case "TCP":
$this->protocol['tag'] = "TCP";
$this->protocol['type'] = SOCK_STREAM;
$this->protocol['proto'] = SOL_TCP;
break;
case "UDP":
$this->protocol['tag'] = "UDP";
$this->protocol['type'] = SOCK_DGRAM;
$this->protocol['proto'] = SOL_UDP;
break;
default:
$this->error("","Protocol /"$proto/" is not a valid Socket-protocol-type!/nUse TCP/UPD Quit../n",1);
//exitpoint
}
return True;
}
function set_family($family = "AF_INET"){
$this->method = "set_family";
$family = strtoupper($family);
switch($family){
case "AF_INET":
$this->family = AF_INET;
break;
case "AF_UNIX":
$this->family = AF_UNIX;
break;
default:
$this->error("","Type /"$family/" is not a valid Socket-family!/nUse AF_INET/AF_UNIX Quit../n",1);
//exitpoint
}
return True;
}
function accept() {
$this->method = "accept";
if (!($conn_id = socket_accept($this->Socket))){
$this->Error($this->Socket,"failed !/n");
}else{
$this->add_socket($conn_id);
return $conn_id;
}
}
function set_option($level,$option,$value){
$this->method = "set_option";
if (!socket_set_option($this->Socket, $level, $option, $value)) {
$this->Error($this->Socket,"Values: ($level,$option,$value) failed !/n");
}
}
function bind ($adress_or_path = "0.0.0.0" , $port){
$this->method = "bind";
if(!$adress_or_path){$adress_or_path = "0.0.0.0";}
if($this->family == "AF_UNIX"){
$port = 0;
$sockfile = "/tmp/D2Dsock_".getmypid().".sock";
if($adress_or_path == "0.0.0.0"){
$adress_or_path = $sockfile;
if(!$this->isdir("/tmp")){
$this->error("","Cant not use default path /"/tmp//" to create socketfile !/nDirectory does not exists/nUse bind() with existing path",1);
//exitpoint
}
}
$pathparts = pathinfo($adress_or_path);
if(!$pathparts['extension'] || !$pathparts['basename']){
$this->error("","/"$adress_or_path/" is no valid filename! Useage /path/name.extension /n",1);
//exitpoint
}
if(!$this->isdir($pathparts[dirname])){
$this->error("","Cant not use path /"$pathparts[dirname]/" to create socketfile ! Directory does not exists/n",1);
//exitpoint
}
if(file_exists($adress_or_path)){
$this->error("","Socketfile already exists: /"$adress_or_path/"! Delete, if the socket is not in use anymore/n",1);
//exitpoint
}
if(!$fp = @fopen($adress_or_path,"w+")){
$this->error("","Cant create socketfile in: /"$adress_or_path/"! Make sure we have permissions to do this/n",1);
//exitpoint;
}else{
fclose($fp);
unlink($adress_or_path);
}
}
//echo $adress_or_path;
if (!socket_bind($this->Socket, $adress_or_path, $port)) {
$this->error($this->Socket,"Values: ($adress_or_path, $port) failed !/n",1);
//exitpoint
}
$this->myhost = $adress_or_path;
$this->myport = $port;
return True;
}
function listen ($adress_or_path = "0.0.0.0", $port){
$this->method = "listen";
$this->set_option(SOL_SOCKET, SO_REUSEADDR, 1);
$this->bind($adress_or_path, $port);
if (($ret = socket_listen($this->Socket,15)) < 0 ) {
$this->error($this->Socket,"Values: ($adress_or_path,$port) failed !/n",1);
//exitpoint
}
$this->add_socket($this->Socket);
return $this->Socket;
}
function block($deskriptor=null, $block = true) {
$this->method = "block";
if(!$deskriptor){
$deskriptor = $this->Socket;
}
if(!$block){
if(!socket_set_nonblock($deskriptor)){
$this->Error($deskriptor,"NoneBlock failed !/n");
return False;
}
}else {
if(!socket_set_block($deskriptor)){
$this->Error($deskriptor,"Block failed !/n");
return False;
}
}
return True;
}
function can_read() {
$this->method = "can_read";
$read = $this->clients;
//һѡִеsocket
if(false === socket_select($read, $write = NULL, $set_e = NULL, 0, 0)){
$this->Error("","Socket_select() failed !/n");
$read = Array();
}
return $read;
}
function can_write() {
$this->method = "can_write";
$write = $this->clients;
if( false === socket_select($read, $write = NULL, $set_e = NULL, 0, 0)){
$this->Error("","Socket_select() failed !/n");
$write = Array();
}
return $write;
}
function write($deskriptor, $string = "/x0", $incl_mypipe = FALSE) {
$this->method = "write";
if($deskriptor == $this->Socket && !$incl_mypipe){
//dont wirte into my own pipe -> gives error broken pipe
//Dunno if this will be needed anytime ? then set to true
return;
}
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if($res = socket_write($deskriptor, $string) ){
$this->socketinfo[$deskriptor]['last'] = time();
return $res;
}
$this->error($deskriptor);
return false;
}
function send($deskriptor,$string, $host, $port = null) {
$this->method = "send";
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
// Send a packet when using UDP.
if(socket_sendto($deskriptor, $string, strlen($string), 0, gethostbyname($host), $port)){
$this->socketinfo[$deskriptor]['last'] = time();
return true;
}
$this->error($deskriptor,"Host: /"$host/", Port: /"$port/" failed !/n");
return false;
}
function recv($deskriptor, $len) {
$this->method = "recv";
// Recieve from a socket when using UDP.
$buf = null;
$host = null;
$port = null;
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
// var_dump($deskriptor);
//MSG_WAITALL
//if(@socket_recvfrom($deskriptor, $buf, $len, 0, $host, $port)){
if(@socket_recvfrom($deskriptor, $buf, $len, MSG_WAITALL, $host, $port)){
$this->socketinfo[$deskriptor]['last'] = time();
return array($buf, $host, $port);
}
//$this->error($deskriptor);
return false;
}
function binary_read($deskriptor, $length = 1024) {
$this->method = "binary_read";
// Reads $length number of bytes without stopping at /n or /r.
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if (FALSE === ($buf = socket_read ($deskriptor, $length, PHP_BINARY_READ))) {
$this->error($deskriptor);
}
$this->socketinfo[$deskriptor]['last'] = time();
return $buf;
}
function read($deskriptor, $length = 1024) {
$this->method = "read";
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
$read = "";
if (($read = socket_read($deskriptor, $length, PHP_NORMAL_READ)) === false) {
if ($read != ''){
$this->error($deskriptor);
} else {
if($deskriptor!=$this->Socket)
$this->close($deskriptor);
return FALSE;
}
} else {
$this->socketinfo[$deskriptor]['last'] = time();
$read = str_replace("/r", '', $read);
$read = str_replace("/n", '', $read);
if($read){return $read;}
return NULL;
}
}
function shutdown($deskriptor=null, $how = "ALL") {
$this->method = "shutdown";
switch(strtoupper($how)){
case "ALL":
$how = 2;
break;
case "READ":
$how = 0;
break;
case "WRITE":
$how = 1;
break;
default:
$this->error("","Socket Shutdown /"$how/" is not valid !/nUse ALL/READ/WRITE");
return False;
}
if(!$deskriptor){
$deskriptor = $this->Socket;
}
if (socket_shutdown($deskriptor, $how)<0){
$this->error($deskriptor);
}
return true;
}
function close($deskriptor=null) {
$this->method = "close";
if(!$deskriptor){
//Shutdown ALL incl. Me
while (list ($id, $sock) = each ($this->clients)) {
if($sock != $this->Socket){
socket_close($sock);
}
}
if($this->family == AF_UNIX && file_exists($this->myhost)){
unlink($this->myhost);
}
socket_close($this->Socket);
$this->clients = "";
$this->socketinfo = "";
$this->Socket = "";
return True;
}
$this->remove_socket($deskriptor);
socket_close($deskriptor);
return True;
}
function add_socket ($socket){
$this->method = "add_socket";
$this->clients[] = $socket;
if($socket != $this->Socket){
$ip = $this->get_ip($socket);
$this->socketinfo[$socket]['ip'] = $ip;
$this->socketinfo[$socket]['host'] = $this->get_host($ip);
} else {
//its me ...
// $this->socketinfo[$socket]['ip'] = $this->myhost;
// $this->socketinfo[$socket]['host'] = "not supported";
}
$this->socketinfo[$socket]['started'] = time();
$this->socketinfo[$socket]['last'] = time();
}
function remove_socket($deskriptor){
$this->method = "remove_socket";
$sockets = ARRAY();
reset($this->clients);
foreach($this->clients as $sock) {
if($deskriptor != $sock){
$sockets[] = $sock;
}
}
$this->remove_socketinfo($deskriptor);
$this->clients = $sockets;
}
function get_socketinfo($deskriptor="", $field = ""){
$this->method = "get_socketinfo";
if(!$deskriptor){
return $this->socketinfo;
}
if(!$this->socketinfo[$deskriptor]){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
if($field){
return $this->socketinfo[$deskriptor][$field];
}
return $this->socketinfo[$deskriptor];
}
function set_socketinfo($deskriptor, $field, $value){
$this->method = "set_socketinfo";
if(in_array($field,array("ip","host","started","last"))){
$this->Error("","Field /"$field/" is already in use by system/n");
return False;
}
$this->socketinfo[$deskriptor][$field] = $value;
return True;
}
function remove_socketinfo($deskriptor){
$this->method = "remove_socketinfo";
$infos = ARRAY();
$this->socketinfo[$deskriptor] = "";
reset($this->socketinfo);
while (list ($id, $sock) = each ($this->socketinfo)) {
if($sock){
$infos[$id] = $sock;
}
}
$this->socketinfo = $infos;
}
function get_host($ip){
$this->method = "get_host";
if($this->family == AF_INET ){
if(!$ip){
$this->Error("","Not a valid IP /"$ip/" given");
return false;
}
return gethostbyaddr($ip);
}
return "localhost";
}
function get_ip ($deskriptor){
$this->method = "get_ip";
if($this->family == AF_INET ){
if(!$deskriptor){
$this->Error("","No valid socketdescriptor(id) given !/n");
return false;
}
socket_getpeername($deskriptor, &$addr);
if(!$addr){
return false;
}
return $addr;
}
return $this->mypath;
}
function debug_print($message){
if($this->opener){
echo nl2br($message);
return;
}
echo "$message";
return;
}
function isdir($directory){
return ((@fileperms("$directory") & 0x4000) == 0x4000);
}
function Error($deskriptor="", $message = "", $critical = FALSE) {
$headline = "Error in :".__CLASS__."::".$this->method."()";
if(!$critical){
if($message){$headline = "$headline/n->$message";}
if($deskriptor){$headline.= "/n->".@socket_strerror(socket_last_error($deskriptor));}
$this->debug_print("$headline/n");
return;
}
$msg = "Socketstatus below:/n";
$msg.= 'Last deskriptor status: '.@socket_strerror(socket_last_error($deskriptor))."/n";
$msg.= 'Last socket status: '.@socket_strerror(socket_last_error($this->Socket))."/n";
$msg.= "AT: ".__LINE__ ."/nIn:". __FILE__;
$this->debug_print("CRITICAL ERROR !/n$headline/n$message/n$msg/nSocke dying....");
exit();
}
function enable_broadcast() {
//SO_BROADCAST = $00020;
if(($ret = socket_set_option($this->Socket, SOL_SOCKET, SO_BROADCAST, 1)) < 0) {
$this->error("Failed to enable broadcast option.");
}
}
function disable_broadcast() {
if(($ret = socket_set_option($this->Socket, SOL_SOCKET, SO_BROADCAST, 0)) < 0) {
$this->error("Failed to disable broadcast option.");
}
}
}
?>
// SAGPnPServer.cpp
/*************************************************************
used to test PnPClient
author: Xie Guangyong
data : 2008-10-29
modify history:
*************************************************************/
#include "stdafx.h"
#include <winsock2.h>
#include <string>
#include <list>
#include <iostream>
#include <process.h>
#include <stdlib.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define UDP_PORT 7001
#define TCP_PORT 7002
#define MSG_PNP_SEARCH_SERVER 0x01
#define MSG_PNP_SERVER_ACK 0x02
#define MSG_PNP_CLIENT_MAC 0x05
#define MSG_PNP_REG_INFO 0x04
#define MSG_PNP_SAG_ACK_RECV 0x07
#define MSG_PNP_SAG_ACK 0x09
#define MSG_PNP_HEART_BEAT 0x0b
#define MSG_PNP_HEART_BEAT_ACK 0x08
#define MSG_PNP_FILE_NOT_FOUND 0x06
typedef struct EsPnPTcpMsg
{
unsigned char msg_hdr;
unsigned char msg_len[4];
unsigned char msg_type;
char msg_content[10*1024];
}EsPnPMsg;
// global variables
typedef list<SOCKADDR_IN> sockaddr_list;
char g_msgBufer[10*1024];
UINT32 g_fileLen;
sockaddr_list g_slClient; //客户列表
HANDLE g_hThread[2];
typedef unsigned int uint;
void PnPConvertStringToIntLength(unsigned char* strLen,uint bufLen,int* actLen)
{
int i =0;
if(strLen == NULL || bufLen !=4)
{
printf("[PNP] convert string to int length params error/n");
*actLen = -1;
return ;
}
*actLen = 0;
*actLen = (*(strLen+3)) +(*(strLen+2) << 8) + (*(strLen+1) << 16) +(*(strLen+0) << 24);
printf("[PNP] convert string %2d %2d %2d %2d to int %d/n",*strLen,*(strLen+1),*(strLen+2),*(strLen+3),*actLen);
return ;
}
/*将整形长度转换为字符串成功返回0, 否则返回-1*/
int PnPConvertIntToStringLength(UINT32 iLen,unsigned char* strLen,uint bufLen)
{
if(iLen <0 || strLen == NULL || bufLen!=4)
{
printf("[PNP]convert int to string length params error/n");
return -1;
}
*(strLen + 3) = (iLen & 0xff000000) >> 24;
*(strLen + 2) = (iLen & 0x00ff0000) >> 16;
*(strLen + 1) = (iLen & 0x0000ff00) >> 8;
*(strLen + 0) = (iLen & 0x000000ff);
printf("[PNP]convert int %d to string %d %d %d %d/n",iLen,*(strLen+0),*(strLen+1),*(strLen+2),*(strLen+3));
return 0;
}
int readFiletobuffer(char* sName)
{
FILE *stream;
int i, numread;
g_fileLen = 0;
char FilName[255];
memset(FilName,0,255);
sprintf(FilName,"%s%s",sName,".xml");
memset(g_msgBufer,0,sizeof(g_msgBufer));
/* Open file in text mode: */
if( (stream = fopen( FilName, "rb" )) != NULL )
{
/* Attempt to read in 25 characters */
i = 0;
while((numread = fread(g_msgBufer+i*25,1,25,stream)) == 25)
{
g_fileLen += numread;
i++;
}
g_fileLen += numread;
printf( "Number of items read = %d/n", g_fileLen );
fclose( stream );
}
else
{
printf( "File could not be opened/n" );
return -1;
}
return 0;
}
// 监听PnP客户端的广播查询包,并回应客户端
DWORD GetClient(LPVOID param)
{
SOCKET sockListen;
SOCKADDR_IN sin_local;
SOCKADDR_IN sin_client;
int len;
EsPnPMsg msgBuf;
EsPnPMsg sendBuf;
UNREFERENCED_PARAMETER(param);
sockListen = socket(AF_INET,SOCK_DGRAM,0);
if((sockListen) == INVALID_SOCKET)
{
cerr<<"can't create socket"<<endl;
return 1;
}
memset(&sin_local,0,sizeof(sin_local));
sin_local.sin_addr.s_addr = htonl(INADDR_ANY);
sin_local.sin_family = AF_INET;
sin_local.sin_port = htons(UDP_PORT);
if(bind(sockListen,(SOCKADDR FAR *)&sin_local,sizeof(sin_local)) == SOCKET_ERROR)
{
cerr<<"can't bind"<<endl;
closesocket(sockListen);
return 1;
}
len = sizeof(SOCKADDR);
char clientAddr[30];
int bulen;
while(TRUE)
{
memset(&msgBuf,0,sizeof(msgBuf));
memset(&sin_client,0,sizeof(sin_client));
recvfrom(sockListen,(char*)&msgBuf,sizeof(msgBuf),0,(SOCKADDR*)&sin_client,&len);
//recv(sockListen,(char*)&msgBuf,sizeof(msgBuf),0);
printf("recv msg = %x %x %x %x %x %x/n",msgBuf.msg_hdr,msgBuf.msg_len[0],msgBuf.msg_len[1],msgBuf.msg_len[2],msgBuf.msg_len[3],msgBuf.msg_type);
if((msgBuf.msg_hdr)== 0x7e)
{
switch((msgBuf.msg_type))
{
//收到SAG发过来的请求消息
case MSG_PNP_SEARCH_SERVER:
cout<<"find a client,ip ="<<inet_ntoa(sin_client.sin_addr)<<endl;
g_slClient.push_back(sin_client); //保存客户端地址备用
PnPConvertStringToIntLength(msgBuf.msg_len,sizeof(msgBuf.msg_len),&bulen);
memset((char*)&clientAddr,0,sizeof(clientAddr));
strncpy(clientAddr,msgBuf.msg_content,bulen);
cout<<"get a client mac = "<<clientAddr<<endl;
//回应SAG
memset(&sendBuf,0,sizeof(sendBuf));
sendBuf.msg_hdr = (0x7e);
sendBuf.msg_type = (MSG_PNP_SERVER_ACK);
//sprintf(sendBuf.msg_len ,"%d",0);
sendto(sockListen,(char*)&sendBuf,
sizeof(sendBuf)-sizeof(sendBuf.msg_content),
0,(SOCKADDR FAR *)&sin_client,sizeof(sin_client));
cout<<"send ack to client ip ="<<inet_ntoa(sin_client.sin_addr)<<endl;
break;
//暂时不考虑其它情况
default:
break;
}
}
}
return 0;
}
// 读取配置文件数据到结构体
DWORD RWThread(LPVOID lParam)
{
SOCKET sockListen,sockRW;
EsPnPMsg recvBuff,sendBuff;
SOCKADDR_IN sin_remote;
int len;
sockListen = *((SOCKET*)lParam);
len = sizeof(sin_remote);
sockRW = accept(sockListen,(SOCKADDR FAR*)&sin_remote,&len);
if(sockRW == INVALID_SOCKET)
{
cerr<<"accpet error"<<endl;
return -1;
}
printf("a new client %s has connected/n",inet_ntoa(sin_remote.sin_addr) );
BOOL bOptVal = TRUE;
if (setsockopt(sockRW, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, sizeof(BOOL)) != SOCKET_ERROR) {
printf("Set SO_KEEPALIVE: ON/n");
}
while(TRUE)
{
memset(&recvBuff,0,sizeof(recvBuff));
recv(sockRW,(char*)&recvBuff,sizeof(recvBuff),0);
if((recvBuff.msg_hdr) == 0x7e)
{
PnPConvertStringToIntLength(recvBuff.msg_len,sizeof(recvBuff.msg_len),&len);
printf("recv msg = %x %x %d /n",(recvBuff.msg_hdr),(recvBuff.msg_type),len);
for(int i = 0;i<len;i++)
{
printf("%3d",recvBuff.msg_content[i]);
}
printf("/n");
switch ((recvBuff.msg_type))
{
//收到SAG的MAC地址,查找文件,并发送相关数据给SAG
case MSG_PNP_HEART_BEAT:
memset(&sendBuff,0,sizeof(sendBuff));
sendBuff.msg_hdr = 0x7e;
sendBuff.msg_type = MSG_PNP_HEART_BEAT_ACK;
//sprintf(sendBuff.msg_len,"%d",0);
if(send(sockRW,(char*)&sendBuff,sizeof(sendBuff) - sizeof(sendBuff.msg_content),0) == SOCKET_ERROR)
{
cerr<<"send msg to client error"<<endl;
}
break;
case MSG_PNP_CLIENT_MAC:
char macAddr[20];
memset(macAddr,0,20);
PnPConvertStringToIntLength(recvBuff.msg_len,sizeof(recvBuff.msg_len),&len);
memcpy(macAddr,recvBuff.msg_content,len);//atoi(recvBuff.msg_len));
printf("len = %d mac : %s /n",len,macAddr);
{
cout<<"start sending config data to sag"<<endl;
if(readFiletobuffer(macAddr) <0)
{
memset(&sendBuff,0,sizeof(sendBuff));
sendBuff.msg_hdr = 0x7e;
sendBuff.msg_type = MSG_PNP_FILE_NOT_FOUND;
if(send(sockRW,(char*)&sendBuff,sizeof(sendBuff)-sizeof(sendBuff.msg_content),0)==ERROR)
{
cout<<"can't send not file message to sag"<<endl;
}
cout<<" send not data to sag";
}
else
{
memset(&sendBuff,0,sizeof(sendBuff));
sendBuff.msg_hdr = (0x7e);
sendBuff.msg_type =( MSG_PNP_REG_INFO);
PnPConvertIntToStringLength(g_fileLen,(sendBuff.msg_len),sizeof(sendBuff.msg_len));
memcpy((char*)sendBuff.msg_content,g_msgBufer,g_fileLen);
if(send(sockRW,(char*)&sendBuff ,g_fileLen+6,0) == SOCKET_ERROR)
{
cerr<<"send msg to client error"<<endl;
}
cout<<"send "<< g_fileLen <<" to client"<<endl;
}
}
break;
case MSG_PNP_SAG_ACK_RECV:
cout<<"sag recv config data"<<endl;
break;
case MSG_PNP_SAG_ACK:
cout<<"sag applied config data"<<endl;
break;
default:
break;
}
}
}
return 0;
}
//与客户端进行数据交
DWORD PnPServerTCP(LPVOID param)
{
UNREFERENCED_PARAMETER(param);
SOCKET sockListen;
SOCKADDR_IN sin_local;
int optval;
fd_set fdSetAccpt;
sockListen = socket(AF_INET,SOCK_STREAM,0);
if(sockListen == INVALID_SOCKET)
{
cerr<<"can't create listen sock"<<endl;
return -1;
}
memset(&sin_local,0,sizeof(sin_local));
sin_local.sin_family = AF_INET;
sin_local.sin_port = htons(TCP_PORT);
sin_local.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockListen,(SOCKADDR FAR *)&sin_local,sizeof(sin_local) )== SOCKET_ERROR)
{
cerr<<"bind error"<<endl;
return -1;
}
optval = 0;
if(setsockopt(sockListen,SOL_SOCKET,SO_KEEPALIVE,(char*)&optval,sizeof(optval)) == SOCKET_ERROR)
{
cerr<<"setsockopt error"<<endl;
return -1;
}
if(listen(sockListen,SOMAXCONN) == SOCKET_ERROR)
{
cerr<<"listen error"<<endl;
return -1;
}
while(TRUE)
{
FD_ZERO(&fdSetAccpt);
FD_SET(sockListen,&fdSetAccpt);
if(select(FD_SETSIZE,&fdSetAccpt,NULL,NULL,NULL) > 0)
{
if(FD_ISSET(sockListen,&fdSetAccpt))
{
if( CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RWThread,(LPVOID)&sockListen,0,NULL) == NULL)
{
cerr<<"create thread error"<<endl;
}
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// initialize winsockstack
WSADATA wsData;
if(WSAStartup(MAKEWORD(2,2),&wsData) != 0)
{
cerr<<"can't startup winsock stack"<<endl;
return -1;
}
// set console titile
HWND hwnd = GetForegroundWindow();
SetWindowText(hwnd,_T("PnP Server"));
cout<<"PnP Server running"<<endl;
//spawn a thread to contiously get new client
g_hThread[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)GetClient,NULL,0,NULL);
if(g_hThread[0] == NULL)
{
cerr<<"create thread getclient error"<<endl;
return -1;
}
g_hThread[1] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PnPServerTCP,NULL,0,NULL);
if(g_hThread[1] == NULL)
{
cerr<<"create thread pnpservertcp error"<<endl;
return -1;
}
if( WaitForMultipleObjects(2,g_hThread,TRUE,INFINITE) == WAIT_OBJECT_0)
{
cout<<"PnP server terminated"<<endl;
WSACleanup();
return 0;
}
return 0; //never execute
}