早速今朝この目覚ましで起きたら異常に目覚めが良くて7時前に会社に着いちゃった。
始業2時間前。アホだ。
で、前回の続きなわけだけど、サーバを作るなんて高等技術は俺には無いから、当然誰か偉い人が書いたプログラムをパクる。
「サーバを作る C言語」でググって見つけた、68user's page様の、
「ネットワークプログラミングの基礎知識 >> C 言語で echo サーバを作ってみよう (1)」
にあるソースを元に、今回の目的のサーバを作る。
やりたいことは簡単。
任意のポートで待って、接続されたら kill `pidof mpg123` を実行する。
シンプルにこんだけ。
これに、成功したかどうかを返すよーな親切機能を付け加えたりするのは気分次第。
こいつは、stop_mp3_serverと名付けよう。
* Name : stop_mp3_server.c
*
* Action: ****番ポートで待ち受けて、接続があったらmpg123をkillする。
*
* 2007.06.14 Ver.0.01 Genki edit.
* refer to echo-server-1.c by
* http://x68000.q-e-d.net/~68user/net/c-echo-1.html
*
*
* Ver.0.01 とりあえずAction通りに動く。
* 結果によってsuccess or errorを返す。
************************************************************************
* Origin
* $Id: echo-server-1.c,v 1.6 2005/02/19 16:01:53 68user Exp $
*
* echo サーバサンプル
*
* written by 68user http://X68000.q-e-d.net/~68user/
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]){
int connected_socket, listening_socket;
struct sockaddr_in sin;
int len, ret;
int sock_optval = 1;
int port = ****;
/* リスニングソケットを作成 */
listening_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( listening_socket == -1 ){
perror("socket");
exit(1);
}
/* ソケットオプション設定 */
if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
&sock_optval, sizeof(sock_optval)) == -1 ){
perror("setsockopt");
exit(1);
}
/* アドレスファミリ・ポート番号・IPアドレス設定 */
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
/* ソケットにアドレス(=名前)を割り付ける */
if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){
perror("bind");
exit(1);
}
/* ポートを見張るよう、OS に命令する */
ret = listen(listening_socket, SOMAXCONN);
if ( ret == -1 ){
perror("listen");
exit(1);
}
printf("ポート %d を見張ります。\n", port);
struct hostent *peer_host;
struct sockaddr_in peer_sin;
len = sizeof(peer_sin);
/* コネクション受け付け */
connected_socket = accept(listening_socket, (struct sockaddr *)&peer_sin, &len);
if ( connected_socket == -1 ){
perror("accept");
exit(1);
}
/* ここから Genki wrote */
if(!system("kill `pidof mpg123`")){
write(connected_socket,"success",7);
}else{
write(connected_socket,"error",5);
}
ret = close(connected_socket);
return 0;
}
そう。俺が書いたのは5行だけ。
しかも何なら
else write(connected_socket,"error",5);
こう書いてやりゃ2行だ。
で、この5行(ないし2行)の意味は、
とりあえずif文の条件の中で、killコマンドを発行しちゃうわけで。
たまたまkillコマンドってのは成功したら黙ってるから、結果が空っぽなら成功なんだろーなって感じで、"success"って文字列を接続してきたクライアントに送ってやる。
で、エラーだったらゴタゴタ抜かすので、そんなときは"error"って文字列を。
こんだけで事足りる。
そんで、このサーバに携帯から刺激を与えるためのPHPスクリプト。
仮にstop_mp3.phpと名付けよう。
<?PHP
/*************************************************************************************************
Name:stop_mp3.php
Action:MP3再生の目覚ましを止める
2007.06.13 Ver.0.01 Genki wrote
Spec.
Ver.0.01 正しいパス送ったらボタン出る。ボタン押したらソケット開く。
***************************************************************************************************/
//各種設定
mb_internal_encoding("euc-jp");
// NOTICEエラー出さないように
// 編集・テスト動作時はコメントアウトすること。
error_reporting(E_ALL & ~E_NOTICE);
$pass = abcdef;
$port = 99999;
?>
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/php; charset=euc-jp">
<TITLE>
Stop mp3
</TITLE>
</HEAD>
<BODY bgcolor="#CCCCCC">
Stop mp3<BR><BR>
<?PHP
$p = $_POST['p'];
$a = $_POST['a'];
if($p == $pass){
if($a == "yes"){
$sock = fsockopen("localhost",$port) or print "ストップサーバ動いてない";
$msg = fgets($sock,1024);
if($msg == "success"){
echo "止めた";
}elseif($msg == "error"){
echo "止めれなかった";
}
}else{
echo <<<EOF
<FORM action="./index.php" method="post">
<INPUT type="hidden" name="p" value="$pass">
<INPUT type="hidden" name="a" value="yes">
<INPUT type="submit" value="Stop mp3">
</FORM>
EOF;
}
}else{
echo <<<EOF
<FORM action="./index.php" method="post">
<INPUT type="password" name="p" maxlength=12>
<INPUT type="submit" value="Login">
</FORM>
EOF;
}
echo <<<EOF
</BODY>
</HTML>
EOF;
?>
こいつの動作は、
- 正しいパスが送られてなかったらパスワード入力フォームを表示。
- パスが送られてても、a=yesが無かったらストップボタンを表示。
(これを画面メモすれば、ボタンを押すだけで止めれるってページを作るため。)
- パスとa=yesが揃ったら、stop_mp3_serverのソケットを開く。
となる。
で、ソケット開いた結果帰ってきた$msgの内容によって、「止めた」「止めれんかった」のメッセージを表示。
接続エラーなら、「サーバ動いてへん」と表示。
ここで、素敵なスキルアップを果たした。
この行、printがechoでは動かんかった。
戻り値の無いechoではor演算の対象にならず、文法エラーが出るって感じかな?
初めてprintじゃないとダメな状況に遭遇しました。
数日前に分からんっつってたことが、いきなり分かった。
YSAK
むふふ、だから言ったでしょう。
printの勝利だw
printはn以外は同じ列にあるからタイピングしやすい
echoは列がほとんど重複してないから打ちにくい。
したがって、printの逆転勝利。
うが~っ!