メールを受信したり、送信したりを 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 までのデーターをメモリーに格納する場合のコードを書いてみます。
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() 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() 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