

# やろうとしていること

C言語で構造体をtcpのソケットを用いて送受信しようとしています。  
#include <sys/stat.h>で定義がされている  
struct statをそのまま送りたいと考えていました。

# 問題点

struct statをネットワークバイトオーダー(ビッグエンディアン)に変換したいと思い、メンバ変数を一つずつ変換する処理を書いていたところでした。  
struct
statのメンバ変数にはmtime,atime,blksizeなどlong型に相当する変数が存在していまして、私のマシンは64bitなのでこれらの変数は8byteです。つまり、8byteのデータを送信する必要があるのでバイトオーダーの変換をしようとしましたが、  
バイトオーダー変換用の関数として#include
<arpa.inet.h>に含まれている関数を探すとhtonsやhtonlぐらいで2byte,4byteを変換する関数しか見つかりませんでした。自作して使っても良いのですけど、なぜ8byte用が実装されていないのでしょうか？  
32bitマシンとの通信ができないからという理由もありそうですが、そうだとしたら上記のstruct
statはそのまま変換せずに最大4byteに各メンバ変数を調整するべきということでしょうか？

# お聞きしたいこと

なぜ8byteのバイトオーダー変換は公に実装されていないのか？（あったとしても見つからない)  
そもそも32bitマシンと64bitマシンは通信することはよくあるのか？  
です。

まとまっていなくて申し訳ありませんが、もしここらへんの常識を教えていただけますなら宜しくおねがいします。


CC BY-SA 4.0
2022-07-26T06:11:51.747
90197
2022-08-03T02:31:14.153
2022-07-26T06:22:55.480
3060
53689
question
linux c network
8byteのデータをネットワークバイトオーダーに変換することはよくあるのか？していいのか？


オイラなら `struct stat` をそのまま（バイナリ形式で）出力しようとはこれっぽっちも思いません。 [man
stat](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/stat.2.html) によると

  * 特定メンバ `st_dev` や `st_ino` が存在すること

は決まっていますが、では

  * その具体的サイズやバイトオフセットやエンディアンネス
  * 値の意味づけ
  * 値がいつ更新されるか
  * 文書化されていないメンバの有無だの意味だの

などは決まっていません。よって `struct stat` のバイナリ内容は [linux](/questions/tagged/linux
"'linux' のタグが付いた質問を表示") 以外の OS との互換性など一切ありませんし、同一の Linux ディストリビューションであっても
x86/x64
では違うでしょうし、どうせプラットフォーム依存なのだったらバイト列をそのまま送受信してしまえばよいのでネットワークエンディアネスに変換する必然すら感じません。

ということで、そもそもその仕様間違っていませんか（案件分析ヘマってませんか）あたりから再提案することになりそうです。

で、質問に対する回答としては `ntohl()`
等が作られた当時ネットワークというのはとてつもなく高価につく代物だったのでそこに乗せる電文は最短長にしたかった、つまり１つの項目が 64bit
も使うような何かを電文に使うなど考えもしなかった（から 64bit な変換関数はその昔には作られなかった
）ということになりそうです。すでにコメントにあるように、今ならばある、ってことで。

* * *

cygwin64 と hpux の `sys/stat.h`
の中を読んでみた。この中身をネットワーク越しに別マシンに転送し、別マシン上で役に立つ気がしないので、やはり案件分析からやり直しだと判断するっス。典型的
[XY 問題](https://ja.meta.stackoverflow.com/questions/2701/)
（あるいは[こっち](https://ja.wikipedia.org/wiki/XY%E5%95%8F%E9%A1%8C)）ですね。

* * *

コメントより

> 当方学生でして、案件分析もない個人プロジェクトでした

案件分析って何か特別なことだと思ってます？報告書にしたためて上司の印もらって社内報告書データベースに永久保存する？ なわけないです。

案件分析って「やりたいこと」（開始時点では脳内でも整理されてない）に言葉という形を与えて、それを実現するのにできそうなことを探すってだけのことっス。今回オイラがやった
`struct stat` の中身を読んで検討するってのも立派に案件分析。 `st_ino` や `st_uid`
はこのマシンでのみ有効で、ネットワークの向こうのマシンにとっては同じ値でも意味が違う、という分析をすれば、これをそのままネットワーク電文に流しても意味ないと判断できます。じゃあ何をどうネットワークの向こうのマシンに渡せば意味がある？ってのはまた別の案件分析。仕様を決める＝案件分析なので、だれでも毎日やってるはずですよ。


CC BY-SA 4.0
2022-07-26T11:50:30.703
90205
2022-07-28T00:56:25.627
2022-07-28T00:56:25.627
8589
8589
90197
answer


> そもそも32bitマシンと64bitマシンは通信することはよくあるのか？

OSの話に限れば、最近のデスクトップPCに限れば、もうかなりの割合で64bit化が進んでいるので、あまりないです。長期稼働している業務・産業用PC等では、ちょいちょい32bit環境が残っているケースがありますが。ただし、OSは64bitでも、その上で動作しているプログラムは32bitのものが多数存在します。

アーキテクチャ・環境に依存したベタなバイナリをやり取りするのは使い勝手がよろしくないので、もっと汎用的のあるデータ形式とプロトコルを選定する所から始めた方がよいと思います。そもそも、どういった用途を想定していますか？

基本的に、ファイルデータのようにありのままのデータを送る必要が無ければ、テキストデータにした方が、送受信したデータ内容の確認がしやすいです。ログ出力すれば、そのまま人間が読めるので。

測定器のように、もう何をやり取りするかが決定しているなら、固定長テキスト+CRLF
のような単純なアスキーテキストをベタで送るとかでもよいでしょうし、データ形式の変動が大きい、複雑なデータをやり取りするなら json+HTTP(S)
のような汎用性の高い組み合わせを採用した方がよいでしょう。

広く使用されているデータ形式とプロトコルを採用すれば、開発言語が変わろうが環境が変わろうが、それらが扱えるライブラリがほぼ確実に存在するので、通信するのが圧倒的に楽になります。


CC BY-SA 4.0
2022-08-03T00:33:18.603
90346
2022-08-03T00:47:08.427
2022-08-03T00:47:08.427
41943
41943
90197
answer


32ビットマシンだとか64ビットマシンだとか呼ばれているのは CPU が一度に扱える幅のことだと考えておおよそ間違いありません。
一つの命令で処理できないのなら二個・三個の命令に分けて処理すれば良いだけのことですので、32ビットマシンで64ビット幅の値を扱えないということはありません。
現在の C の言語仕様では long long int 型を必須としており、またこの型が 64
ビット以上の幅を持つという規定もありますが、32ビットマシン用にコンパイルすることは問題なく出来ます。

それはそれとして 64 ビットの値として扱う意味があるかどうかは個別の事情によるので必要であれば使うこともあるということになるでしょう。
ある研究資料によるとプログラムの中に現れる整数は 10 ビット以下 (で表現可能な値) が 92% を占め、 30 ビット以下が 95%
を占めるというデータがあります。 つまり小さい値のほうが圧倒的に多く出現するのです。 もちろんプログラムの性質で大きく左右されるものではありますが、要するに
32 ビットでだいたい足りてしまうのでコンピュータ自体が 64 ビットマシンであってもデータ形式としては 32
ビットを選択するというのはごく普通にあります。

あるいは、ほとんどは小さい値のはずだけれどたまにある大きな値にも対応したいというときは可変長な符号化をする例もあります。 具体的な事例としては
WebSocket の [payload
length](https://datatracker.ietf.org/doc/html/rfc6455#section-5.2)
(データの大きさを表す値) はたった 7 ビットしか割り当てられていませんが、値が 126 または 127 のときは続く 16 ビットまたは 64
ビットを使うといった具合です。

エンディアンについても、通信規格を制定する上ではビッグエンディアンを基本にする習慣がありますがアプリケーション層で流れるデータの様式には制約はありません。

様々な表現が有りうるのでどれを選ぶかは必要性次第です。 32 ビットで UNIX
時間を表現しようとすると[2038年問題](https://ja.wikipedia.org/wiki/2038%E5%B9%B4%E5%95%8F%E9%A1%8C)がありますが、短期間しか使わないプログラムであると割り切るのであればそれはそれで間違った判断ではありません。
何が正しいかは何が必要かで決まります。


CC BY-SA 4.0
2022-08-03T02:31:14.153
90349
2022-08-03T02:31:14.153
3364
90197
answer