質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Network+

Network+とは、IT業界団体CompTIA認定のネットワーク技術に関する知識を証明する資格です。ネットワーク技術者として、実務で必要なネットワークセキュリティ・ネットワークアーキテクチャなどの知識を取得している証明となります。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

8byte(long,double)をネットワークバイトオーダーに変換することはあるのか?していいのか?

yonde
yonde

総合スコア1

Network+

Network+とは、IT業界団体CompTIA認定のネットワーク技術に関する知識を証明する資格です。ネットワーク技術者として、実務で必要なネットワークセキュリティ・ネットワークアーキテクチャなどの知識を取得している証明となります。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

3回答

0グッド

0クリップ

808閲覧

投稿2022/07/26 05:57

編集2022/07/26 08:13

やろうとしていること

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マシンは通信することはよくあるのか?
です。

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

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

2

なぜ8byteのバイトオーダー変換は公に実装されていないのか?(あったとしても見つからない)

linux限定ですが、以下の関数が提供されています。(私は使ったことはありませんので参考程度にしてください)
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/endian.3.html

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

送信元、送信先で送受信データを取り決める場合、そもそも、相手方のマシンが何ビットかを考慮する必要はありません。8バイトのデータを送られた場合、受け取った側は、32ビットマシンであろうが、64ビットマシンであろうが、それをきちんと処理しなければいけません。もし、受け手が処理できないなら、最初にそのような取り決めをしてはいけません。(32ビットマシンでも8バイト整数は処置可能です。linuxならlong long int型で処理可能)
ネットワークバイトオーダーで送るのが、伝送時の決め事となっていますが、私の知っている範囲では、これを律儀に守っているのは日本の会社だけのように思われます。実際に中国の上海とか深センとかから送られてくるデータは、リトルエンディアンのデータになっているケースが多いです。(欧米からバイナリデータを受けたことはないので欧米については不明)
現実的には、送り側も受け側もインテル系のCPUなので、お互いにリトルエンディアンのほうが簡単です。
(ひと昔はSPARC系もあったのでビッグエンディアンのほうが良かったのですが・・・)
日本の会社では、律儀に、ビッグエンディアンを採用するので、送り側がリトルエンディアン→ビッグエンディアン
変換を行い、受け側が、ビッグエンディアン→リトルエンディアンを行っています。これはお互いにとって不幸なことのようにも思われます。
この辺にも規則に縛られる日本人と規則にとらわれず現実的な利益を優先する中国人との違いが表れています。
(どちらにも一長一短はありますが)
「32bitマシンと64bitマシンは通信することはよくあるのか」の対する直接的な答えは、「よくあるが、相手方のマシンのBitサイズを意識する必要はない」になります。

投稿2022/07/26 07:16

tatsu99

総合スコア4985

HidekoSaeki, yonde👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

yonde

2022/07/26 07:33

ご回答有り難うございます。 私の場合、送受信側でデータ形式は取り決めるつもりでしたので、確かに一般的な慣習に無理に合わせる必要もないということはよく理解できました。 バイトオーダーに関する現代の環境についてもご指導いただきありがとうございます。

2

ベストアンサー

8 byte 用がないということはなくて、Windows と macOS なら htonll() ntohll()、Linux なら htobe64() be64toh() があります。

8 byte のバイナリの値を送受信するメジャーなプロトコルは思い当たりませんが、もちろんそういうプロトコルを定義しても構いません。主流はバイナリよりはテキスト化して送受信することな気がします。

投稿2022/07/26 06:35

編集2022/07/26 06:36
int32_t

総合スコア17880

tmp, yonde👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

yonde

2022/07/26 07:24

ご回答有り難うございます。 環境別に関数があることを知りませんでした。 テキスト化して送受信するとなるとJSON形式で表現してシリアライズするのも良いですね。

1

結局は送信側と受信側で解釈が一致していればよいのであなたがプロトコルに関する裁量を持っていて送信側も受信側も作るのであればどう実装しようと自由です。 習慣的にネットワーク上のデータの流通にはネットワークバイトオーダ (ビッグエンディアン) を使うことになっていますが、リトルエンディアンで統一するのであればそれでも問題ありません。

64bit 版のバイトオーダ変換関数がある環境もありますが、無い場合もありますし、あったとしても名前や使い方が異なったりもします。 そういった違いは configure で吸収するのですが……「64bit 用のバイトオーダ変換関数がその環境にあればそれを使って無ければ自分で定義したものを使う」などとするよりは常に自分で定義してしまったほうがてっとり早いです。

現代では構造体 (などの各プログラミング言語におけるデータ表現) をバイト列に対応付けるのは既存のシリアライザを導入する方法が好まれ、 Protocol Buffers がよく用いられるようです。 つまり、変換を自分で書くという状況自体を避けるということです。

投稿2022/07/26 07:03

SaitoAtsushi

総合スコア5038

yonde👍を押しています

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

yonde

2022/07/26 07:27

ご回答有り難うございます。 grpcを用いた構造体の送受信も考えていたのですが、やろうとしていることの割には高機能でビルドが大変そうで敬遠していました。 この期にもう一度腰を据えて試してみようと思います。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Network+

Network+とは、IT業界団体CompTIA認定のネットワーク技術に関する知識を証明する資格です。ネットワーク技術者として、実務で必要なネットワークセキュリティ・ネットワークアーキテクチャなどの知識を取得している証明となります。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。