FORTH:ナノサーバーとナノクライアント。 パート1

素晴らしいフォート言語を使用する別の側面について話をする時が来ました。

この一連の記事では、それを使用して小さなクライアント/サーバーアプリケーションを作成する方法を示します。 それぞれが研究および教育ツールとして使用できます。

エンターテインメントには、最大7台のWindowsとSP-Forthパッケージが必要です。 Andrei Cherezovは、Linuxで彼の砦システムを起動する可能性を宣言しましたが、私はそれをチェックしませんでした。



最初に、参加しているクライアントに十分な簡単なサーバープログラムを作成してみましょう...サーバーの現在の日付と時刻を見てみましょう。





spf4.exeファイルと同じフォルダーに、メモ帳またはその他のテキストエディター(Akelpad)でdatetimes.fファイルを作成します。



サーバーを作成するには何が必要ですか? ソケット!

それらの作業を開始するには、適切なライブラリを接続する必要があります。

〜nn \ lib \ sock2.f



便利なことに、すべてのライブラリはソースコードに保存されます。 あなたはいつでもそれが何であり、どのように機能するかを見て見ることができます。



 0 VALUEソックス
 0 VALUE sockt_a
 SocketsStartup THROW。(ソケットが開始されました)CR 
 CreateSocket THROW TO sockt。(ソケット作成)CR


最初の2行は明らかに変数の定義です。 VALUE変数は、従来のFortを改善したものです。 これにより、無限の参照解除(アドレスで値を取得)を回避し、テキストを読みやすくすることができます。

3行目はそれ自身を表しており、最後の行にはいくつかのコメントを与える必要があります。

CreateSoketという言葉は明確で真実ですが、微妙な違いがあります。 ソケットは異なります! 正直なところ、私はソケットの種類についてあまり知りませんが、最も単純で、最も頻繁に使用されるものは、この言葉で作成されたブロッキング双方向TCP / IPストリームソケットです。 異なるタイプのソケットを作成する方法は、ライブラリを調べることができます。 マジックワードTHROWはエラーコードのみをインターセプトし、エラーコードがゼロ以外の場合に例外をスローします。 ブラケットは、端末上でそれらの間のテキスト、CR-改行を印刷します。

 
 80 sockt BindSocket THROW。(ソケットバインド)CR
 sockt ListenSocket THROW。(リスン)CR
 sockt AcceptSocket THROW TO sockt_a。(からの接続を受け入れます:) 


ほとんどすべてです。 誰かがノックするまで、ポート80に座って聞きます。

もちろん、完全に任意の空きポートを選択できます。

AcceptSoketという単語は、接続するまでプログラムを停止します。

誰が私たちとつながっていますか?



 sockt_a GetPeerIP&Port THROW SWAP NtoA TYPE。 "port:"。 


コンソールへの接続元のIPアドレスとポートを表示します。 プログラム全体で唯一のSWAPが発生したのは、 GetPeerIP&Portという単語の実装があまりよく考えられていないためです。



発送の日時を準備します。

別のライブラリが必要になります



lib \ include \ facil.f



TIME&DATEという単語が必要です。 (ライブラリで修正する必要がありましたが、今では完全なものとは異なります。ミリ秒を出力し始め、日付の順序も変更されました。)この単語は7つの値をスタックに置きます。 ミリ秒、秒、時間、年、月、日。 したがって、最初の番号はスタックから削除されます。 これは月の日を指します。



  S "現在の時間:sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(日)
 S "-" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(月)
 S "-" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(年)
 S "" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(時間)
 S "-" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(分)
 S "-" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(秒)
 S "-" sockt_a WriteSocket THROW
 S> D(D.)sockt_a WriteSocket THROW(ミリ秒) 




ひどいですね。 フォートの美しさは、この不名誉をキャンディーに変えることができるということです。

同じテキストが3で7回と2回繰り返されていることがわかります。もちろん、ループを作成することはできますが、テキストは読みにくくなります。

砦を利用してください。



追加の単語を定義する



  :send_value S> D(D.)sockt_a WriteSocket THROW;
 :send_delimeter sockt_a WriteSocket THROW; 




論理的で明確で読みやすい。 {注:S> Dという単語は、スタックの最上位要素を倍精度のマークで展開します。 単語(D.)は、倍精度の数値を文字列に変換し、そのアドレスとカウンターをスタックにプッシュします。}



 :日send_value;
 :月send_value;
 :年send_value;
 :時間send_value;
 :分send_value;
 :秒send_value;
 :ミリ秒send_value; 




まだひどい。 何ができますか?

Fort言語の重要な機能の1つが助けになります。 独自の定義語を作成できます。



 :make_value CREATE DOES> DROP send_value;
 :make_values 0 DO make_value LOOP; 




実行中のmake_valueという単語は、スペースで制限された入力ストリームから次の文字セットを選択し、現在の辞書の最上部に配置します。 この新しく発見された単語の意味は、 DOES>の後の単語によって与えられます。 つまり、共通のセマンティクスによって統合された概念を作成できるツールがあります。



  7 make_values日月年時分秒秒ミリ秒 




そして区切り文字のために



 :make_delimeter CREATE、DOES> 1 send_delimeter;
 :make_delimeters 0 DO make_delimeter LOOP;

 BL CHAR-CHAR:3 make_delimeters:-_ 




今、私たちは美しく書くことができます



日時
日-月-年_時間:分:秒:ミリ秒 




接続を引き裂く



  sockt_a CloseSocket THROW 




そして、ソケットをクリアします



  SocketsCleanup THROW 




それだけです



ご覧のとおり、実行とコンパイルの段階は交互に行われます。 これは砦のもう一つの基本的な特徴です。 また、よく書かれたFortプログラムは、ほとんどコメントを必要としません。

十分注意していた人は、基本的な単語コロンとマイナスを再定義したことに気付きました。 これをどうするか? 答えは以下です。



コームドコード



 〜nn \ lib \ sock2.f 
 lib \ include \ facil.f

 80定数ポート
 0 VALUEソックス
 0 VALUE sockt_a

 :send_value S> D(D.)sockt_a WriteSocket THROW;
 :send_delimeter sockt_a WriteSocket THROW;

 :make_value CREATE DOES> DROP send_value;
 :make_values 0 DO make_value LOOP;

 7 make_values日月年時分秒秒ミリ秒 

 :make_delimeter CREATE、DOES> 1 send_delimeter;
 :make_delimeters 0 DO make_delimeter LOOP;

 :define ::;

 BL CHAR-CHAR:3 make_delimeters:-_



定義:時間と日付サーバー 

                 SocketsStartup THROW。「ソケットが開始されました」CR 
                 CreateSocketはsocktに投げます。「Socket created」CR

                ポートソックBindSocket THROW。 "Socket binded" CR
                 sockt ListenSocket THROW。 "Listen" CR

                 sockt AcceptSocket sockt_aへのスロー「接続の受け入れ元:」 
                 sockt_a GetPeerIP&Port THROW SWAP NtoA TYPE。 "port:"。 

                 S "現在の時刻:" sockt_a WriteSocket THROW

                日時 

                日-月-年_時間:分:秒:ミリ秒  

                 sockt_a CloseSocket THROW 

                 SocketsCleanup THROW 
 ;

時刻と日付サーバー  



All Articles