LoginSignup
1
0

More than 1 year has passed since last update.

Dart で プログラマブルなメールサービスを作ろう (1) Network Byte Order

Last updated at Posted at 2021-12-25

メールを受信したり、送信したりを Pure Dart で実装していこうという趣旨の記事です。全30回くらいの内容になります。

また、メールの送受信は Gmail などの メールプロバイダーを経由しないで、自信のDart が動作するLinuxサーバーを経由して行う方式を取ります。

特定のメールに対して自動返信できる用になりますので、メール配信方のゲームを作成したり。自動で会員登録処理をしたり。簡単な質問に答えるAIを間に入れたりなど、Dart で組む事が出来るようになります。

また、 Pure Dart で 組んでいくので、ネットワークの知識がつきます。DNS や SMTP などの知識が得る効能があります。

- SMTP

サーバー間でおメールを受信するには、SMTPプロトコルが利用されます。
https://datatracker.ietf.org/doc/html/rfc5321

- DNS

メールの送信先のIPアドレスを調べたり。送信相手が、なりすましをしていないかの判定にしようします。

https://datatracker.ietf.org/doc/html/rfc1034
https://datatracker.ietf.org/doc/html/rfc1035
https://datatracker.ietf.org/doc/html/rfc3901

INDEX

(1) Dart で プログラマブルなメールサービスを作ろう (1) Network Byte Order
(2) Dart で プログラマブルなメールサービスを作ろう (2) DNS 用のQuery を組んでみる
(3) Dart で プログラマブルなメールサービスを作ろう (3) DNS の Compression

Network Byte Order

第一回は、ネットワークバイトオーダーについて解説します。

1バイトのデーターをメモリーに格納していく場合、特別問題はありません。

例えば、0 から 16 までのデーターをメモリーに格納する場合のコードを書いてみます。

main.dart
import 'dart:typed_data' show Uint8List;

String toHex(Uint8List buffer) {
  const List<String> vv = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
    var b = StringBuffer();
    for (var i = 0; i < buffer.length; i++) {
      var v = buffer[i];
      var v1 = (v >> 4) & 0xF;
      var v2 = v & 0xF;
      b.write('${vv[v1]}${vv[v2]}');
    }
    return b.toString();
}

main() async {
  var input = <int>[0x00, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f];  
  var buffer = Uint8List(16);
  for(var i=0;i<input.length;i++){
    buffer[i] = input[i] & 0xFF;
  }
  print(toHex(buffer));
}

これを実行すると、000102030405060708090a0b0c0d0e0f といったデータが出力されます。

ただし、問題になるのは、2byte の short型のデータ、4byteの int型のデータ
などはどのようにメモリーに記録すると良いでしょうか..

いくつか記録方法があるのですが、2つの記録方法が主流です。
- ビッグエンディアン
0x1234 をメモリーに記録した場合、[0x12,0x34] と記録される
- リトルエンディアン
0x1234 をメモリーに記録した場合、[0x34,0x12] と記録される

リトルエンディアン で格納してみる

main.dart
main() async {
  var input = 0x1234;
  var buffer = Uint8List(2);

  //print(((input>>8) & 0xFF).toRadixString(16)); --> 12
  //print((input & 0xFF).toRadixString(16)); --> 34
  buffer[0] = input & 0xFF;
  buffer[1] = (input>>8) & 0xFF;
  print(toHex(buffer));
}

もしも、リトルエンディアンなら、0x34 0x12 と順に表示されるはずです。
もしも、ビッグエンディアンなら、0x12 0x32 と順に表示されるはずです。

これを実行すると、3412 と返すので、無事、リトルエンディアンで格納できました。

ビックエンディアン で格納してみる

main.dart
main() async {
  var input = 0x1234;
  var buffer = Uint8List(2);

  //print(((input>>8) & 0xFF).toRadixString(16)); --> 12
  // print((input & 0xFF).toRadixString(16)); --> 34
  buffer[0] = (input>>8) & 0xFF;
  buffer[1] = input & 0xFF;
  print(toHex(buffer));
}

これを実行すると、1234 と返すので、無事、ビックエンディアンで格納できました。

※ Dart だと Dart2か Dart1の後半でAPIが追加されたはずです..が見つからない..

通信プロトコルはビックエンディアン

今回は、DNS と SMTP のプロトコルを実装していくのですが、これらはRFCに仕様が記載されています。 このこれらのプロトコルでは、特に記載がなければ、ビックエンディアンでデータがやりとりされます。

次回

DNS から データーを MXレコードと TXTレコードと、Aレコードを、取得する機能を Pure Dart で 書いていく予定です。

REF

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0