システムプログラム(第6回): marshaling/unmarshaling

                                       筑波大学 システム情報系 情報工学域
                                       新城 靖
                                       <yas@cs.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.coins.tsukuba.ac.jp/~syspro/2018/2018-05-23 /marshaling.html
あるいは、次のページから手繰っていくこともできます。
http://www.coins.tsukuba.ac.jp/~syspro/2018/
http://www.coins.tsukuba.ac.jp/~yas/

marshaling/unmarshaling

プログラム中のデータ項目とネットワーク上を流れるメッセージに対応づける。
marshaling (整列化)
メモリ中からデータ項目を集めて、ネットワークでメッセージとして 転送するのに適した形式にまとめる。
unmarshaling (非整列化)
逆。
英語の綴りは、l が1つのものと2つのもの(イギリス綴り)がある。教科書によって違う。

プロセスAがメモリ中のデータを1個にまとめてネットワークに送り出す。プロセスBが受け取り元に戻す
図? marshalingとunmarshaling

4個の要素からなる構造体を整列化して送信している。 整列化する基本的な方法 ネットワークからデータを受け取ると、先頭から解釈して元のデータを再現す る。

ネットワーク上を流れている時には、整列化された データの先頭にはネットワークのヘッダが付加されている。

整数のmarshaling

分散プログラムでは、メッセージを送信するプロセスと受信するプロセスが異 なる CPU で実行されることがある。整数をmarshalingする時には、次のような 点を考慮する必要がある。

バイト・オーダ

整数を送るだけでも、バイトオーダに気をつける必要がある。

C言語で扱える整数

(現在のコンピュータのほとんどは、バイト単位でアドレスを付けているので、 1バイトの整数については、バイトオーダの問題はない。)

2バイト、または、4バイトの整数をメモリに保存する方法 : メモリの下位番地に上位バイトを置くか下位バイトを置くか

リトルエンディアン
下位番地に下位バイトを置く。x86 (Intel Pentium/Core, AMD Athlon/Phenom)。
ビッグエンディアン。
下位番地に上位バイトを置く。PowerPC, SPARC, m68k
PowerPC は、両方切り替え可能だが、ビッグエンディアンで使うことが多い。

0x12345678 が CPU とメモリに置かれている。
図? バイト・オーダ

バイト・オーダが異なることも考慮した整数の送受信

現在、ネットワーク・バイト・オーダとしては、ビッグエンディアンが広く 使われている。

バイトオーダを変換するライブラリ関数

名前 方向 ビット数
uint32_t htonl(uint32_t hostlong) ホストからネットワークへ変換 32ビット
uint16_t htons(uint16_t hostshort) ホストからネットワークへ変換 16ビット
uint32_t ntohl(uint32_t netlong) ネットワークからホストへ変換 32ビット
uint16_t ntohs(uint16_t netshort) ネットワークからホストへ変換 16ビット

htonl() を使った整数の送信

unsigned long int hostlong, netlong;    
hostlong = 0x12345678 ;    
netlong = htonl( hostlong );    
send(conn, &netlong, sizeof(netlong), 0);

snprintf()/strtol()

snprintf() で文字列に直して送り、strtol() や atoi() でもどす方法もある。 文字列文化。インターネットのアプリケーションでよく使われる。

送信側:

    char buf[BUFSIZE];
    hostlong = 0x12345678 ;    
    snprintf(buf,BUFSIZE,"%d\n",hostlong );
    send(conn, buf, strlen(buf), 0);
思ったほど遅くはない。

注意:sscanf() は、整数をデコードするために使う分には問題ないが、 文字列を受け取るために使うとバッファ・オーバーフローが生じる可能性があるので、 使わない方がよい。

文字列のmarshaling


Last updated: 2018/05/21 14:36:44
Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>