スキップしてメイン コンテンツに移動

魔法のハコ-ESE-UPnP

魔法のハコはつないだだけでつながる。
よく家電とか、、プリンタとか、ネットワークケーブルをつないだだけで使えるものがある。
あれみたいなものだ。

つながるということは、

  • こっちから見つけに行く
  • 向こうから見つけてもらう

のどちらかだ。
魔法のハコクライアント(MHC)は、魔法のハコサーバ(MHS)に見つけてもらうということで考える。
実際には、【MHCがネットワークにつながったとき、マルチキャストパケットをLOCALネットワーク上に投げて、MHSにキャッチしてもらう】という方法にする。

実際には、
(1)MHSがUDPでマルチキャストパケットを受け取るようにしておく。
(2)MHCがマルチキャストを投げる。
(3)MHSがマルチキャストを受け取り、投げ元のIPに対して、TCPでMHCに情報を送る。

UDPはマルチキャストパケットの時のみ使用。そのあとは、互いのIPがわかるので、TCP/IPででれでれ情報交換するという形である。
その後、MHCはWebSocketでMHSとつながることになる。

クライアントの方はPHPで書くとこんな感じ。
試しにJSONをbase64して送っているけど、とりあえず今は使っていない。
 $udp_port = 41900;
 $tcp_port = 41901;

 $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
 socket_set_option( $sock,IPPROTO_IP,MCAST_JOIN_GROUP, array( 'group'=>'239.255.255.250', 'interface'=>0 ));
 $msgAR      = array();
 $IP       = getHostByName(getHostName());
 $msgAR["system"]["ip"]  = $IP;
 $msgAR["system"]["type"] = "checker";
 $msg = json_encode($msgAR);
 $a64= base64_encode( $msg );
 $msg = "FINRED\n{$a64}\n\n";
 $send_ret = socket_sendto( $sock, $msg, strlen( $msg ), 0, '239.255.255.250', $udp_port);
 socket_close( $sock );
 // 一旦おくりつけてこのsocketは終了
 // 今度はTCPで受け取る
 $sock  = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
// socket_bind($sock,$IP,41901);
// socket_bind($sock,'127.0.0.1',$tcp_port);
 socket_bind($sock,'0.0.0.0',$tcp_port);
 socket_listen($sock, 10);
 $remote  = socket_accept($sock);
 $data  = socket_read($remote, 4096);
 echo "data:{$data}";

サーバの方はこんな感じで。
 $port = 41900;
 $IP  = getHostByName(getHostName());

 //UDPのソケット作成
 $sock = socket_create(AF_INET,SOCK_DGRAM,SOL_UDP);
 socket_bind($sock,'0.0.0.0',$port);  // 成功
 socket_set_option( $sock
  ,IPPROTO_IP
  ,MCAST_JOIN_GROUP
  , array( 'group'=>'239.255.255.250', 'interface'=>0 )
 );
 $from = '';
 while(true){
  //UDPのソケットを受信
  $buf="";
  socket_recvfrom($sock,$buf,4096,0,$from,$port);
  $idx = strpos($buf,"FINRED");
  if($idx === 0) echo "\n------({$idx})------------------------------------------\nbuf:{$buf}\n";
  else   echo ".";
  $v = substr($buf,6);
  $v = base64_decode($v);
  $j = json_decode($v,true);
  $ip  = $j["system"]["ip"];
  $type = $j["system"]["type"];
  echo "\nip:{$ip}  type:{$type}\n";
  echo "from:{$from}  port:{$port}\n";
  usleep(1000000);
  $msg = "FINERD RETURN\nIP:{$IP}";
  // TCPで送りつける
  $socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
  socket_connect($socket, $from,41901);
  socket_write($socket, $msg, strlen($msg));
        socket_close($socket);
 }
 //close socket
 socket_close($sock);


実行してみたところ(o^^o)

コメント

このブログの人気の投稿

平面的な台形変形と奥行的な台形変形(2)

ということで前回のつづきですが、 3点の消点でやってみます。 ●元 ●平面的変形(もはや台形じゃないけど^^;) ●立体的変形の平面投影っぽく ●無理やり感満載の3消点 こんな感じとなりますね。 void getDaikeiPersPos(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double* pX,double* pY,double tx,double ty,double delt){ double xa,ya,xb,yb,xa2,ya2,xb2,yb2; xa = ya = xb = yb = xa2 = ya2 = xb2 = yb2 = 0; getDaikeiPersPosX(x1,y1,x2,y2,x3,y3,x4,y4 ,&xa,&ya,&xb,&yb ,tx,delt); getDaikeiPersPosY(x1,y1,x2,y2,x3,y3,x4,y4 ,&xa2,&ya2,&xb2,&yb2 ,ty,delt); bool b = vCrossPoint(xa,ya, xb,yb, xa2,ya2, xb2,yb2,pX,pY); } void getDaikeiPersPosX(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4 ,double* xa,double* ya,double* xb,double* yb,double t,double delt){ if(t<0) t = 0; if(t>1) t = 1; double xa1,ya1,xa2,ya2,xa3,ya3,xa4,ya4,xa5,ya5,xa6,ya6; double cx,cy,xx,yy; xa1 = ya1 = xa2 = ya2 = xa3 = ya3 = xa4 = ya4 = xa5 = ya5 = xa6 = ya6 = 0; cx = cy = xx = yy = 0; double tA = ...

Ratchet@PHPで自宅にhttpsでWebsocketするサンプルを動かす

今日のゴールは、外から自宅にhttpsでWebsocket@Rachet@PHP@WindowsServerするサンプルを動かすことです。 ※そのうち、Websocket@libwebsocket@Ubuntuをやりますね。 そもそもRatchetはポートを指定してws:// をうけつけてくれるものなので、 自宅サーバがそもそもNginxでリバースプロキシしてるので、 難しいことはせずに、それに則った形で設定を行います。 要するに、wss://をリバースプロキシで受けて、Ratchetが動作するサーバへ転送するだけです。 もちろん、プロキシにはUpgradeヘッダ(HTTP 1.1)への対応が必要となりますね。 絵にかくと、以下ですね。 自宅のhttpsはletsencryptというのを使用しています。 Windowsで使う場合には、以下が参考になりますね。 https://webbibouroku.com/Blog/Article/letsencrypt-setting ここではHTTPSそのものの設定に関しては記述しませんです。 リバースプロキシしてるNginxのconfの該当部分は以下としました。 ※abcd.comは実際のドメインに。 server { listen 443; include ssl-abcd.com.conf; server_name ws.abcd.com; proxy_set_header Host $http_host; access_log /log/ssl-ws-abcd.com.log main; location / { proxy_pass http://192.168.xxx.xxx:8080; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; } } これによって、javascriptから、 wss://ws.abcd.com が、 http:192.168.xxx.xxx:8080 に転送されることになるので、転送先にRatc...

意外とめんどいPHPからshellとかexecをWindowsでする場合の話。

いや、意外とめんどい話でした。 たとえば、CMD(BAT)ファイルで以下を実行させてみます。 ●TEST.cmd● REM ------------------- start a.exe start b.exe REM ------------------- pause そう、a.exeもb.exeも実行され、終了を待つことなくpause入ります。 そう、じゃぁ、phpで、以下をやってみます。 shell_exec('TEST.cmd' ); あれこれ とか exec('TEST.cmd' ); あれこれ すると、どうでしょう。 このa.exeとb.exeが両方終わるまで、待たされてしまい、 【あれこれ】のとこに来てくれません。 やりっぱなし! ができないのです。 うぅーん。LinuxでPHPならforkとかできる(ハズな)んだけど。 どうなってんだろ。これ(>_<) ここ、トリッキーないかがわしいことやればできるのかもしれないけど (できないかもですが^^;) つきつめるとこじゃないので、 どうせ最後はC++にするつもりなので、Jobコントローラーの部分なので、 素直にC++で描いてしまおうかとも思ったけど、 いろいろ調べた結果、psexecでできそうな感じもしたんだけど、 やってみるとできない。うぅーーん。 できるかぎりPHP という方針、若干、無理があったかな^^; じゃぁ、ってことで、プロセスを立ち上げっぱなしで戻ってくるEXEを作ってみた結果、 CreateProcessだと戻ってこない ShellExecuteなら戻ってくる ということがわかったので、そういうEXEを経由し、 exec("redshell -proc:php.exe z.php"); exec("redshell -proc:php.exe z2.php"); って感じで連続実行させるテストをしてみます。 ●a.php <?php exec("redshell -proc:php.exe z.php"); exec("redshell -proc:php.exe z2.php"); for($...