我正在尝试构建一个系统来替换我们现有的系统。它是一个音频流媒体系统。当前系统具有封闭的源程序,该程序在摄取数据和音频的PC上运行。我正在使用覆盆子pi和TCP数据来尝试替换当前系统。客户端将数据发送到pi,pi将获取数据并将其记录下来。
我理解它的方式,理论上,它的工作方式是客户端与服务器建立连接。然后,客户端可以通过该连接发送数据,直到它断开连接或连接出现问题。
客户端可以根据需要继续发送数据。在我的情况下,每次字符数量是相同的,但似乎服务器获得第一位数据,然后基本上超时。然后客户端建立另一个连接,它获取该数据,超时并重复。
我知道这是因为发送数据的系统记录了它,客户端上将有10行,但服务器上只有5行。
这是我的代码,我在PHP中这样做是因为我对此更加满意,但是如果能让这个过程变得更简单,我会更改为python或其他东西。
#!/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();
/* nobody/nogroup, change to your host's uid/gid of the non-priv user */
//change_identity(1000, 1000);
/* 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/nowplaying.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);
$station = substr($buf, 0, 6);
$type = substr($buf, 14, 4);
$artist = preg_replace('/\s+/', ' ', substr($buf, 48, 28));
$title = preg_replace('/\s+/', ' ', substr($buf, 20, 28));
$length = substr($buf, 80, 5);
echo "Station is: " . $station . "\n";
echo "Type is: " . $type . "\n";
echo "Song is: " . $artist . " - " . $title . "\n";
echo "Length is: " . $length . "\n";
//postToServer($station, $type, $artist, $title, $length);
//updateIceCastServer($station, $type, $artist, $title, $length);
}
function postToServer($station, $type, $artist, $title, $length)
{
$url = 'http://website.net/data/' . $station . '/';
$data = array('artist' => $artist, 'title' => $title, 'type' => $type, 'length' => $length);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { echo 'failed'; }
var_dump($result);
}
function updateIceCastServer($station, $type, $artist, $title, $length)
{
$username = 'admin';
$password = 'admin';
$url = 'http://ice.mywebserver.net:8000/admin/metadata?mount=/' . $station . '&mode=updinfo&song=' . $artist . ' - ' . $title;
$data = array('artist' => $artist, 'title' => $title, 'type' => $type, 'length' => $length);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Authorization: Basic " . base64_encode("$username:$password"),
'method' => 'POST',
'content' => http_build_query($data),
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { echo 'failed'; }
var_dump($result);
}
/**
* 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();
}
}
?>
&#13;
答案 0 :(得分:0)
我最终为此使用了netcat。用NC打开端口并传递传入的数据要简单得多。
对于我的情况,我最终获取了数据,并向微服务发送了curl请求以完成我需要做的事情。
这是我完成所有这些操作的最终脚本。我运行一个基本的cron作业以保持其运行。
#!/bin/bash
logfile=smdv2.sh.log
today=`date +%Y%m%d`
log=~/$today-$logfile
exec > >(tee -ai $log) && 2>&1
echo "Started listening on port 9000"
nc -klu 9000 | while read line
do
if [ "$line" == '' ]; then
echo "Recieved Blank Line, Skipping"
else
echo "Recieved Line"
echo $line
cart=${line:6:7}
type=${line:13:4}
title=${line:19:28}
length=${line:79:5}
#Data Encoded Post
curl -s \
--data-urlencode "cart=$cart" \
--data-urlencode "type=$type" \
--data-urlencode "title=$title" \
--data-urlencode "length=$length" \
-X POST http://my.server.io/metadata/update
fi
完成