忍者ブログ
え?全力で生きているかって? ――答えはYesだ。当たり前だろそれが人生なんだよ!!
[45]  [46]  [47]  [48]  [49]  [50]  [51]  [52]  [53]  [54]  [55
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

1/31 11:58 ソース修正(getモード時の動作修正)



メールクライアント(メール送受信ソフト)をメインマシンで作るよ。

サーバー設置編読んでなければ先に読んだほうがいいです→サーバー設置編



ソース書く前に、サーバーの動作を再確認。


メールをずっと待ってるサーバーたん
  ↓
メールきた!
  ↓
メールの内容で動作が変わるよ

・メッセージの内容が「get()」やったら
 →ログ(未読メッセージ)をメインマシンに送る(レッドストーントーチ ジュワ...消)
・メッセージの内容が「getall()」やったら
 →全ログ(メッセージ一覧)をメインマシンに送る
・それ以外(hi とか hello とか)やったら
 →ログに書き溜める(レッドストーントーチ  ピッカーン 光)

  ↓
またメールを待つサーバーたん



っていう動作ね。

この中の、メッセージ作って送ったり、get()とかgetall()とか送る部分を今回作るのね。


つまり流れで言うと、

クライアント起動
  ↓
モードが3つ

・メール送信
・get()って送って未読メール受信&表示
・getall()って送ってメール一覧受信&表示

  ↓
終了



じゃぁソースいくで。

今回の環境

・メインマシン→アドバンスドPC。ID=27
・メール受信サーバー→普通のPC。ID=28

再確認だが、コメントは -- (ハイフン2つ)な。

今回のプログラム名はmailでいく。edit mailでエディタ起動。以下ソース




SERVER_ID=28  --サーバーID。28
SERVER_ID=tonumber(SERVER_ID)  --説明省略
 
print("mode?")
write("\tsend,get,getall >")
--モード一覧。send,get,getall
--サーバー設置編でやったアレの通り
--あと、printとwriteの違いだが、
--自動的に改行してくれるかしてくれないかの違い。
--writeは改行してくれない
 
mode=read()
--どのモードかキーボードから読み込み
 
if mode=="send" then
  --send mode
  --メール送信モード
  --正直言うとswitch文で書きたかったけど
  --書式調べんのめんどくさかったからif文で失礼
  
  write("send for? >")
  --受信相手のidを入力
  local id=read()
  --read()ってやることでキーボードから入力できる
  local id=tonumber(id)
  --local ってやつは気にしなくていい。
  --知りたかったら「lua ローカル変数」とかでググって
  
  write("message...>")  
  --メッセージ入力
  local msg=read()
 
  --send message
  --ここで送信
  rednet.send(id,msg)
 
elseif mode=="get" then
  --get mode
  --logファイルを取得する=未読メッセージ受信
  rednet.send(SERVER_ID,"get()")
  --get()ってメッセージをサーバーに送ってやることで、
  --サーバーのlogファイルを取得できるようになる

  --get message(timeout 30sec)
  --タイムアウトの設定を追記
  --30秒たったら受信やめる
  print("message getting...")
  local id,msg=rednet.receive(30)
  
  --show message
  print("\n"..msg)
  --受信したlogファイルを表示
 
  rednet.send(SERVER_ID,"stop()")
  --サーバーはずっとログファイルを送信し続けるから、
  --stop()ってメッセージ送って送信をやめてもらう
 
elseif mode=="getall" then
  --getall mode
  --alllogファイル取得=メッセージ一覧取得
  
  rednet.send(SERVER_ID,"getall()")  --上と同じ
  local event,id,msg=os.pullEvent("rednet_message")
 
  --show message
  print("\n"..msg)
 
  rednet.send(SERVER_ID,"stop()")
 
else
  --print usage
  --使い方説明というか説明になってないけど
  print("mode:")
  print("\tsend:send mail")
  print("\tget:get mail")
  print("\tgetall:get all mail")
  return
end
  
 

ソースコード以上


こっちもソース間違ってるかもしれんからその時はコメントお願いします。



動作イメージはこんな感じ。

まずはsendモード。俺宛のメールは28固定。


2013-01-31_09.18.48.png







次getモード。ちなみに24はメインでもサーバーでもない第3のマシンのID


2013-01-31_09.19.05.png







次getallモード。過去のテストがずらり。


2013-01-31_09.38.33.png






とりあえず以上。

ちなみに、sendで受信サーバー以外にも送れるけど、向こうが受信するかどうかは向こうの状態次第ってやつですね。例えば、第3のマシン(24)からメインマシン(27)にsendで送ろうとすると、メインがrednet.receive()状態じゃないとだめって例のアレですね。



んで、これ書いてる時に、メール無いときにgetモード発動させた時の動作が無いことに気づいたからそのうち修正かけます。でも今の状態でも動作はします。 ←修正済



次、これの応用みたいな感じでチャットツールも作ったからそのうちソース晒します。




謝辞

サーバー用プログラム、クライアントプログラム開発の際、errorcode氏の助言を参考に致しました。ありがとうございました。



以上。


PR
1/31 11:47 ソース修正(if msg=="get()" then 付近からファイルチェック追記)



ということで、メール受信サーバー作ったからソース晒す。

一応このへんとかこのへんとか見ればAPIとか分かりますんで。

基本lua言語ですよ。大丈夫や俺だってこれが初めてなんやから。



ということでソース。の前にいくつかお話。



1つ目。モデムの設定から。


まぁ普通にモデム作るじゃん?shift押しながらマシンに貼っつけるじゃん?でもこれだけじゃぁだめなんだな。律儀にモデムをONにしてやらなきゃならんのだよ。なかなかこだわっとるわ。



ということで、ルートディレクトリにstartupってのを作って、マシン起動時にモデムONになるように設定してやる。startupってのを作ることで、マシン起動したときにそのファイルに書かれたことを実行するようになる。

romディレクトリの中にもあるけどそれとちゃうで!一緒かもしれんけどそれはいじらんほうがいい。ちゃんとルートに作れよ!

cd /
edit startup

って打つとエディタ起動


起動したら

rednet.open("モデムつけた場所")

って書く。モデムつけた場所は、パソコン正面から見て

右:right
左:left
上:top
背面:back

て書けばおk。俺は背面につけたから、rednet.open("back") って書いた。
これもwikiに書いてあるからちゃんと読みましょう。

書いたら、ctrl押してsave、ctrl押してexitでエディタ終了させる。

これで、パソコン起動したらモデムがONになるよ。

試しに、reboot って打ってみ。起動してからモデム見たら赤く光っとるで。完璧やん。



ちなみにrednet.open()だが、プログラム書くときに一番上に書いといてもおk。というか、ソース共有するときだったら書いたほうがいいのかもしれない。が、俺はもうモデムONがデフォという考え方でいく。


これを、サーバー機とメインマシンとどっちもやっとく。


そしてもう一つ。idって打ってどっちもマシンのIDを調べとくこと。メッセージ送信するときに必要。



2つ目。rednetのお話をちょっと。

今回ネックになってるのが、rednet.send()とrednet.receive()の部分。なぜかというと、相手がreceive()で待ち構えている時じゃないとsend()したメッセージが届かないから。

しかしずっとreceive()で待機なんかするわけないやん。作業でけへんもんな。どうしよか。じゃぁ代わりにサーバーたんに受信頼もうよってのが今回の趣旨。

つまり、メッセージを一回サーバーで受信してもらって、それを転送してもらうっていう動作をする。

…面倒ですよね。でもこれでメインマシンで何してても常にメール受信できるんです!何通でもどうぞwwwって感じ。



3つ目。今回のマシン周りの設置

こんな感じ。2つPCあるけど受信サーバーは左側のPC。右側のPCはまだ関係ない。


2013-01-31_08.19.58.png






メール受信したらレッドストーントーチが光るようにしたった


2013-01-31_08.20.49.png







プログラム起動したらこんなかんじでメール受信待機


2013-01-31_08.21.20.png







メッセージ受信したら一応メッセージ表示される。
裏でlogにメッセージ書き貯めていって、また待ち始める。


2013-01-31_08.21.06.png







メインマシンから要求がきたら、今までサーバーが受信したメールを全部転送し始める。



今回作ったプログラムの動作イメージを書くとこんな感じ。



メールをずっと待ってるサーバーたん
  ↓
メールきた!
  ↓
メールの内容で動作が変わるよ

・メッセージの内容が「get()」やったら
 →ログ(未読メッセージ)をメインマシンに送る(レッドストーントーチ ジュワ...消)
・メッセージの内容が「getall()」やったら
 →全ログ(メッセージ一覧)をメインマシンに送る
・それ以外(hi とか hello とか)やったら
 →ログに書き溜める(レッドストーントーチ ピッカーン 光)

  ↓
またメールを待つサーバーたん



という感じ。



じゃぁソース晒そうか。面倒くさがりな俺だがたまにはコメントつけて丁寧に解説しよう

今回の環境を書いとくと、

・メインマシン→アドバンスドPC。ID=27
・メール受信サーバー→普通のPC。ID=28

あと、

・コメントは -- (ハイフン2つ)の部分。luaの仕様。
・日本語のコメントは書けない。書けても書くな。
・英語のコメントは実際に俺も書いた。書かなくてもいいがこれぐらい書いといたほうが後で多少捗るかもね
・「受信ランプ」ってコメントがあるが、受信した時にレッドストーントーチを光らせるように設定したかったらそれ書いて。いらなければ消すかコメントアウトでよろしく。細かい説明は後でする。


今回のプログラム名はpop_serverでいく。ここは好きに変えてもらっておk。

じゃぁ始める。edit pop_server って打ってエディタ起動。以下ソースコード


print("pop server #28\n")
--print()で文字の出力ができる。
--#28ってのはサーバーIDが28だったから
--\nは改行。
 
SEND_ID=27  --メインマシンのID。今回は27
SEND_ID=tonumber(SEND_ID)  --説明省略
 
---------------
--file writer
---------------
--ファイル書き込みする関数を作る
filewriter=function(filename,str)
  --file open
  file=io.open(filename,"a")  --ファイルを追記モードでオープン
 
  --writing
  if file then
    file:write(str)  --ファイルに書き込み
  else
    print("Cannot writing!")  --エラー処理は忘れずに☆
  end
 
  --file close
  file:close()  --ファイルクローズは基本ですよ
 
end
 
--sign off
rs.setOutput("left",true)  --受信ランプ off
 
 
----------
--main
----------
while true do  --無限ループ
  --message get wait
  print("waiting...")  --メッセージ受信待機のとき表示
 
  event,id,msg=os.pullEvent("rednet_message")
  --os.pullEvent("rednet_message")
  --rednet.receive()と見かけの動作は同じ
  --なんでreceive()じゃないかって?大人の事情だよ
  
  print("--------------------")
  print("id:"..id)
  print("msg:"..msg)
  print("--------------------")
  --上の4行は書かなくてもいい。
  --受信したメッセージが見れるだけ
  
  b=false  --(ry
 
  if msg=="get()" then
    --log forwarding
    --今回は未読のメッセージをlogとして保存していく
    --未読メッセージの送信を行う部分

    if fs.exists("/log") then
      --未読メッセージがある場合
    
      --log message load
      logfile=io.open("/log","r")  --/logを読み込みモードでオープン
      logmsg=logfile:read("*a")  --*aでファイル上から下まで読み込み
 
      --message send
      while b==false do  --bがfalseの状態なら無限ループ
        print("sending...")  --送信中表示
        rednet.send(SEND_ID,logmsg)
        --rednet.send(相手ID,メッセージ)でメッセージ送信
        --ここではメインマシンに未読メッセージ送信
      
        id,msg=rednet.receive(2)
        --2秒間だけメッセージ受信
        --ここで「stop()」ってメッセージが来たら送信をやめる
        if msg=="stop()" then
          b=true  --bがtrueになったからループ終了
        end
      end
    else
      --未読メッセージがない場合
      while b==false do
        print("sending...")
        rednet.send(SEND_ID,"Mail is empty.")

        id,msg=rednet.receive(2)

        if msg=="stop()" then
          b=true
        end
      end
    end
 
    --sign off
    rs.setOutput("let",true)  --受信ランプ off
 
    --logfile delete
    fs.delete("/log")
    --ログファイル削除
    --ここで削除することで未読メッセージだけ貯められる
  
  elseif msg=="getall()" then
    --alllog forwarding
    --今度は今まで受信したすべてのメッセージを返す
    --動作自体はさっきの部分と同じ
 
    --alllog message load
    alllogfile=io.open("/alllog","r") 
    alllogmsg=alllogfile:read("*a")
 
    --message send
    while b==false do
      print("sending...")
      rednet.send(SEND_ID,alllogmsg)
      id,msg=rednet.receive(2)
 
      if msg=="stop()" then
b=true
      end
    end
 
    --今回はランプの動作はしないんだよ
    --ログも消す必要ナッシング
 
  else
    --write message to log
    --ログファイルに受信したメッセージを書き込む
    
    --sign on
    rs.setOutput("left",false)  --受信ランプ on
 
    --get minecraft day&time
    --マイクラ内時間の取得。それっぽくね
    time=os.time()  --時間取得
    time=textutils.formatTime(time,flase)  --書式設定
    day=os.day()  --日にち取得。過ごした日数
 
    --write message to file
    --ここで書き込む書式を決めてやってから書き込む
    str_date="date:"..day..","..time.."\n"
    str_msg="id:"..id.."\nmessage:"..msg.."\n"
    str_line="----------------------------\n"
 
    --writing!
    --最初に作った関数を使って書き込む
    --まずはlogのほうから
    filewriter("/log",str_date)
    filewriter("/log",str_msg)
    filewriter("/log",str_line)
 
    --alllogにも書き込み
    filewriter("/alllog",str_date)
    filewriter("/alllog",str_msg)
    filewriter("/alllog",str_line)
 
  end
end
 


ソースコード以上。

もし間違いがあったら遠慮なくコメント欄へ「ここ間違ってるわハゲ!」ってコメントください。
もしそっちの間違いだったらこっちから「間違ってへんわハゲ!」って返すけど。



後回しになったレッドストーントーチのお話な。

rs.setOutput("出力方向",true or false)でレッドストーン回路の出力ができる。

今回、レッドストーン回路がサーバー機の左側にあるから、出力方向はleft。

で、trueとfalseだが、単純にonとoff。このへんはレッドストーントーチの特性みたいなもんを使ったアレなわけだが、スイッチとか使って一応説明しとく。


rs.setOutput("left",true)の状態がこれ


2013-01-31_08.29.54.png






で、rs.setOutput("left",false)の状態がこれ


2013-01-31_08.29.46.png







スイッチがパソコンに変わっただけ。ということ。



で、最後。起動したときにこのプログラムを立ち上げるように設定したかったら設定するといい。

最初に編集したstartupに以下を追加

shell.run("pop_server")

これでマシンが起動したら自動的にプログラムが動作してメール受信待ち状態になる。



動作確認の方法だが、メインマシンで lua て打つとluaが立ち上がる。
ここで、コマンドをいくつか打つと確認ができる。

今回はサーバーIDが28だからそれで行くけどそのへん臨機応変に。

・メッセージ送信
  rednet.send(28,"test")

・未読メッセージ受信
  rednet.send(28,"get()")
  rednet.receive()
  rednet.send(28,"stop()")

・全メッセージ受信
  rednet.send(28,"get()")
  rednet.receive()
  rednet.send(28,"stop()")



ということでメール受信サーバー設置編は以上。

このままではまだ不便ということで、次はメインマシンで使うメールクライアントを作るよ。
 
メール受信サーバー作ったった(クライアント作成編)へ続く


タイトルの通り。


2013-01-31_06.23.55.png






最近MineCraftにComputerCraftとかいうのを導入した。

それのおかげでコンピュータが作れるようになって、ターミナルでコソコソするようなModなわけだが。なんか現実世界とやってることが変わらなさすぎてアレ。



とりあえずこのComputerCraftでいろいろプログラムを書き始めた。

言語はLuaで書くようだ。思ってたより書きやすい。

独自のAPIとかいろいろ充実してるわりには、欲しいプログラムがなかったりする。そこを自分で作って楽しむものなのかもしれない。



ということで、気ままにソースコードとか晒していくことにする。





…結局卒研やってない件。

もうね。ただただつらたんだわ。

そもそもつらたんとか今まで一度も使ったことねぇ言葉だわ。



いやしかし辛い。こうもつらいものかね。というか、辛いというよりかは憂鬱なのかもしれない。



なんというか、もうあと3週間もしないうちに発表しなければならないというのに、ちゃんとした結果が出せていないというか、その過程がちゃんと喋れないというかなんというか。



それなりに今までちゃんとやってきたつもりだし、それなりに出来てはいるけども、あくまでそれなりなんだよな。

仕様がちゃんとしてないのがもんだい。どうも直感的にやりすぎてるっぽい。これはなかなかまずい。






むずかしいですね。



しかし何を言っててもだめ。やらなきゃだめなのだ。つらいつらい。
カレンダー
04 2025/05 06
S M T W T F S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
カウンター
プロフィール
HN:
Mugen
性別:
男性
職業:
社会人だよバカヤローー!!
趣味:
ピアノ、アニメ・音楽鑑賞、ネットサーフィンとかとか
自己紹介:
ただの車好きな変態です。

twitterもやってますんで、よければリンクからドゾー
Twitter




最新CM
[01/14 FreddieSpemo]
[01/13 FreddieSpemo]
[01/13 FreddieSpemo]
[12/21 réplique cartier bracelet]
[12/16 van cleef and arpels alhambra diamond necklace knock off]
バーコード
最新TB
ブログ内検索
アクセス解析
忍者ブログ [PR]