信息倒流php,PHP向客户端广播信息
在網絡中數據傳播分為:Unicast(單播) , Multicast(多播或者組播) 和 Broadcast(廣播)。廣播和多播僅應用于UDP,它們對需將報文同時傳往多個接收者的應用來說十分重要。而 TCP 是一個面向連接的協議,它意味著分別運行于兩主機(由IP地址確定)內的兩進程(由端口號確定)間存在一條連接。廣播地址在默認情況下是不能讓路由器轉發到別的接口的,廣播不能穿越路由器。廣播有以下幾種形式:
受限的廣播:
受限的廣播地址是255.255.255.255,該地址用于主機配置過程中IP數據報的地址,此時,主機可能還不知道它所在網絡的網絡掩碼,甚至連它的IP地址也不知道。在任何情況下,路由器都不轉發目的地址為受限廣播地址的數據報,這樣的數據報只出現在本地網絡中。
指向網絡的廣播:
指向網絡的廣播地址是主機號全為1的地址,A類網絡廣播地址為netid.255.255.255,其中netid為A類網絡的網絡號。
指向子網的廣播:
指向子網的廣播地址是主機號全為1的地址,作為子網直接廣播的IP地址需要知道子網的掩碼。如果B類網絡128.1的子網掩碼是255.255.255.0,則地址128.1.2.255就是對應子網的廣播地址。
指向所有子網的廣播:
指向所有子網的廣播也需要知道目的網絡的子網掩碼。這些廣播地址的子網號和主機號全為1。如果目的子網掩碼是255.255.255.0,那么IP地址128.1.255.255就是一個指向所有子網的廣播地址。
PHP socket 也能實現廣播。在 socket 通信中,實現連接的服務器與客戶端需要綁定同一端口號,端口號表示發送和接收的進程。下面是一個用 PHP 實現的簡單的廣播通信例子,同時采用 PHP 和 C 語言作為客戶端進行測試:
broadcast.php
/* Author @ Huoty
* Date @ 2015-11-17 09:58:25
* Brief @
*/
/* 創建廣播事件 */
function broadcast()
{
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
//使用IPV4格式地址,數據報形式,UDP方式傳輸數據
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); //設置為廣播方式
while ( true ) {
$msg = 'Hi! ' . date("y-m-d h:i:s",time()); //要發送的字符串
socket_sendto($sock, $msg, strlen($msg), 0, "255.255.255.255", 12345);
//發送,255.255.255.255是廣播地址,12345是端口
//echo "Broadcast...\n";
sleep( 2 );
}
socket_close($sock); //關閉
}
/* 創建守護進程 */
$pid = pcntl_fork();
if ($pid < 0)
{
die("fork failed!\n");
}
else if ($pid > 0)
{
exit;
}
else
{
/* 輸出進程ID,便于 kill */
echo "Daemons ID: " . posix_getpid() . "\n";
/* 保持程序的運行 */
set_time_limit(0);
/* 創建一個新的 Session */
$sid = posix_setsid();
if ($sid < 0)
{
exit;
}
/* 改變工作目錄為根目錄 */
chdir("/");
broadcast();
}
?>
client.php
/* Author @ Huoty
* Date @ 2015-11-17 09:58:25
* Brief @
*/
//error_reporting( E_ALL );
set_time_limit( 0 );
ob_implicit_flush();
$socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
if ( $socket === false ) {
echo "socket_create() failed:reason:" . socket_strerror( socket_last_error() ) . "\n";
}
$ok = socket_bind( $socket, '255.255.255.255', 12345 );
if ( $ok === false ) {
echo "socket_bind() failed:reason:" . socket_strerror( socket_last_error( $socket ) );
}
while ( true ) {
$from = "";
$port = 0;
socket_recvfrom( $socket, $buf, 1024, 0, $from, $port );
echo $buf . "\n";
usleep( 1000 );
}
?>
client.c
/* client.c */
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 12345
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
int sockfd, n;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
socklen_t servaddr_len;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
fprintf(stdout, "Accepting connections ...\n");
memset(buf, 0, sizeof(buf));
while ( 1 ) {
n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
if (n == -1)
fprintf(stderr, "recvfrom error");
fprintf(stdout, "%s\n", buf);
memset(buf, 0, sizeof(buf));
}
close(sockfd);
return 0;
}
通常,廣播是需要長時間進行的任務,所以可以創建一個守護進程來完成廣播,以避免程序長時間運行對控制終端的占用。如果不使用守護進程,也可以用 Linux 的 nohup 命令來實現。然而,PHP 的進程控制不能被應用在 Web 服務器環境。那么,要讓 PHP 的進程控制在 Web 環境下得到應用,可以用一個迂回的辦法,即用 cli 的方式執行包含進程控制的 PHP 文件,所謂 cli 方式是指 shell 的執行方式。還有一個需要注意的問題是,在 Web 環境下,由于 PHP 程序是一個死循環,程序一直運行,所以客戶端總是得不到服務器的返回結果。為解決這個問題,可以將用 & 讓程序在后臺運行,同時將輸出重定向到 /dev/null。于是可以創建了一個新文件以保證廣播在 Web 服務器環境下能夠被觸發:
startup.php
/* Author @ Huoty
* Date @ 2015-12-02 16:53:43
* Brief @
*/
exec("php ./broadcast_daemons.php >/dev/null &");
echo "Finished!";
?>
總結
以上是生活随笔為你收集整理的信息倒流php,PHP向客户端广播信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信公众号页面支付接口java,[Jav
- 下一篇: matlab 回音的消除,回声消除AEC