素晴らしいフォート言語を使用する別の側面について話をする時が来ました。
この一連の記事では、それを使用して小さなクライアント/サーバーアプリケーションを作成する方法を示します。 それぞれが研究および教育ツールとして使用できます。
エンターテインメントには、最大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.fTIME&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
;
時刻と日付サーバー