使用PHP捕获通过TCP发送的数据

时间:2017-09-28 18:57:15

标签: php sockets

我正在尝试使用PHP脚本捕获通过tcp套接字从多台计算机发送的数据。看起来我没有获得所有数据,我认为这可能是因为编写脚本的方式。我需要一些帮助。

#!/usr/bin/php -q 
<?php 
/** 
  * Listens for requests and forks on each connection 
  */ 

$__server_listening = true; 

error_reporting(E_ALL); 
set_time_limit(0); 
ob_implicit_flush(); 
declare(ticks = 1); 

become_daemon(); 

/* handle signals */ 
pcntl_signal(SIGTERM, 'sig_handler'); 
pcntl_signal(SIGINT, 'sig_handler'); 
pcntl_signal(SIGCHLD, 'sig_handler'); 

/* change this to your own host / port */ 
server_loop("10.0.3.49", 9009); 

/** 
  * Change the identity to a non-priv user 
  */ 
function change_identity( $uid, $gid ) 
{ 
    if( !posix_setgid( $gid ) ) 
    { 
        print "Unable to setgid to " . $gid . "!\n"; 
        exit; 
    } 

    if( !posix_setuid( $uid ) ) 
    { 
        print "Unable to setuid to " . $uid . "!\n"; 
        exit; 
    } 
} 

/** 
  * Creates a server socket and listens for incoming client connections 
  * @param string $address The address to listen on 
  * @param int $port The port to listen on 
  */ 
function server_loop($address, $port) 
{ 
    GLOBAL $__server_listening; 

    if(($sock = socket_create(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        echo "failed to create socket: ".socket_strerror($sock)."\n"; 
        exit(); 
    } 

    if(($ret = socket_bind($sock, $address, $port)) < 0) 
    { 
        echo "failed to bind socket: ".socket_strerror($ret)."\n"; 
        exit(); 
    } 

    if( ( $ret = socket_listen( $sock, 0 ) ) < 0 ) 
    { 
        echo "failed to listen to socket: ".socket_strerror($ret)."\n"; 
        exit(); 
    } 

    socket_set_nonblock($sock); 
    
    echo "waiting for clients to connect\n"; 

    while ($__server_listening) 
    { 
        $connection = @socket_accept($sock); 
        if ($connection === false) 
        { 
            usleep(100); 
        }elseif ($connection > 0) 
        { 
            handle_client($sock, $connection); 
        }else 
        { 
            echo "error: ".socket_strerror($connection); 
            die; 
        } 
    } 
} 

/** 
  * Signal handler 
  */ 
function sig_handler($sig) 
{ 
    switch($sig) 
    { 
        case SIGTERM: 
        case SIGINT: 
            exit(); 
        break; 

        case SIGCHLD: 
            pcntl_waitpid(-1, $status); 
        break; 
    } 
} 

/** 
  * Handle a new client connection 
  */ 
function handle_client($ssock, $csock) 
{ 
    GLOBAL $__server_listening; 

    $pid = pcntl_fork(); 

    if ($pid == -1) 
    { 
        /* fork failed */ 
        echo "fork failure!\n"; 
        die; 
    }elseif ($pid == 0) 
    { 
        /* child process */ 
        $__server_listening = false; 
        socket_close($ssock); 
        interact($csock); 
        socket_close($csock); 
    }else 
    { 
        socket_close($csock); 
    } 
} 

function interact($socket) 
{ 
    $buf = socket_read($socket, 2048, PHP_NORMAL_READ);

	echo $buf . "\n";

	$file = '/home/pi/09282017.log';

	// Open the file to get existing content
	$current = file_get_contents($file);
	// Append a new person to the file
	$current .= date('Y-m-d h:i:s') . ' ' . $buf . "\n";
	// Write the contents back to the file
	file_put_contents($file, $current);

} 

/** 
  * Become a daemon by forking and closing the parent 
  */ 
function become_daemon() 
{ 
    $pid = pcntl_fork(); 
    
    if ($pid == -1) 
    { 
        /* fork failed */ 
        echo "fork failure!\n"; 
        exit(); 
    }elseif ($pid) 
    { 
        /* close the parent */ 
        exit(); 
    }else 
    { 
        /* child becomes our daemon */ 
        posix_setsid(); 
        chdir('/'); 
        umask(0); 
        return posix_getpid(); 

    } 
} 

?>

我知道它无法正常工作,因为这些机器将数据发送到另一个源,并且它们也在本地登录。发送到此脚本的数据似乎在发送给它的每2-3个中有1个。

我的计划是在网络上放一个覆盆子pi并将所有数据发送给它,然后使用php我会将它发布到api在线用于那里。

1 个答案:

答案 0 :(得分:0)

我最终使用netcat做到了这一点,只是跳过了PHP选项。为什么要重塑意志,对吗?