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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C

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

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

11081閲覧

ソケット通信のデータ型?

sin_250

総合スコア112

C

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

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2017/06/27 13:04

きわめて初歩的な質問だと思うのですが、よろしくお願い致します。

【やりたいこと】
とある目的のため、2台のPCをTCP通信して協調的に動かしたいです。
ざっくり言えば、2台のPC上でそれぞれアプリケーションが動いており、
片方のアプリが停止したらそれをもう片方に伝えてそちら側のアプリが動き出す、みたいなことです。

【言語】
C++です。(が他言語でも本件は同じようなものだと思うので、他言語での回答でも有難いです)

【疑問】
・2台のPC間でTCPのソケット通信をして、メッセージのやり取りをしようと考えています。
・ソケット通信のサンプルプログラムを見ると、
(C言語なら)write(sock, "HELLO", 5), read(sock, buf, sizeof(buf))のように
文字列のやり取りをしているサンプルが多いです。(というかそればかり)。

ソケット通信でメッセージをやり取りする時のデータはどういう形式が王道なのでしょうか?
例えば、上記の例で、片方のPCが相方のPCに「自分のアプリが止まったらそっちで動作開始してね」と伝えたいとき、
片方で

cpp

1write(sock, "I_STOPPED", 9);

として、もう片側で

cpp

1read(sock, buf, sizeof(buf)); 2string result(buf); 3if (result == "I_STOPPED") { 4 I_start(); 5}

などとするのでしょうか?
(・・・なんか違うんじゃないか、文字列で伝えるより洗練されたやり方があるのではないかと思っています。)

浅学で恐縮です。
アドバイスのほどよろしくお願い致します。

以上

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

ソケット通信でメッセージをやり取りする時のデータはどういう形式が王道なのでしょうか?

IP通信するコンピュータ同士は、同じCPUでない可能性を無視できません。
なのでバイナリ形式では互換性が無いこともかなり多いです。特にエンディアンですね。
この問題が発生しにくいので文字列形式が多いのだと思います。バイナリで処理系フリーでやりとりできる仕組みを実装した後、文字列でやり取りしたら、その楽さに感動するレベルです。

単に「停止した」と言うタイミング情報しか送らないのであれば送るデータはなんでも良いと思います。
何か変なパケットが紛れ込んできて誤動作しないよう多少のプロテクトをかける意味で"I_STOPPED"であることを確認するのはありと思います。(プロトコルを知っている悪意のある人がいると簡単にいたずら?されるかも。)

ところで、"I_STOPPED"の送信時、最後のNULL文字を送信していないようです。事前のbufクリアをお忘れなく。

投稿2017/06/27 13:22

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sin_250

2017/06/27 14:41

少し調べなおしてみましたが、おっしゃるようにバイナリデータの送受信は環境によってアラインメント?やエンディアン、int型等のサイズ違いなどの問題があるようですね。 つまりは、テキストベースのやり取りは結構筋よしということなのでしょうか? \0についてはご指摘の通りです。ありがとうございます。 ちなみに、Chironian様がTheolizerの開発者様であることを承知の上でお聞きするのですが、 通信用のメッセージクラスあるいは構造体をシリアライズして送受信する場合でも 上記のようなエンディアンなどの問題は生じるのでしょうか? 質問ばかりで恐縮です。もしご教示頂けましたら幸いです。
Chironian

2017/06/27 15:11

いえいえ、Theolizerを知っていて頂けるだけでもたいへん嬉しいです。 > つまりは、テキストベースのやり取りは結構筋よしということなのでしょうか? htmlが正にそのケースですね。xmlならデータのやり取りもできます。最近のデータのやり取りフォーマットはJsonが流行っているよう思います。 これらは全てテキスト・ベースです。 > 通信用のメッセージクラスあるいは構造体をシリアライズして送受信する場合でも上記のようなエンディアンなどの問題は生じるのでしょうか? Theolizerはバイナリー形式でもエンディアンの問題は発生しないよう設計しています。ただエンディアンの異なるCPUに移植できていないのでテストは出来ていません。orz 異言語間をサポートするProtocol BuffersやMessagePackはフォーマットを確認したことありますがエンディアンを吸収しています。 C++用のシリアライザであるboost::serializationやcerealについては把握していませんが、恐らくエンディアン問題は吸収しているのではないかと思います。 ところで、Theolizerとboost::Asioを使ってTCP/IPでポインタを含む複雑なデータ構造をやり取りするサンプルとその解説を↓に置いてます。 https://theolizer.com/theolizer/tcp_ip_sample/ 同様なことをboost::serializationやcerealでも可能な筈です。シリアライザって便利ですよ。
sin_250

2017/06/30 12:48

なるほど、バイナリ形式でもこういう便利なのを遣えばある程度細かい部分は隠ぺいしてもらえるのですね。 データが小さいならJSONでも十分そうですね。 改めて必要パフォーマンスを考えて決めてみます。ご回答ありがとうございました。
guest

0

ソケット通信でメッセージをやり取りする時のデータはどういう形式が王道なのでしょうか?

ソケット通信(TCP/UDP)はプロトコルスタックの下位レイヤしか提供しませんから、"メッセージ"のやり取りには何らかの上位レイヤ・プロトコル(メッセージフォーマット)を選択する必要があります。

コレを選べば間違いなしと言える程の王道はありませんが、下記プロトコル(ライブラリ)が一般に広く使われているようです:

テキストベースのプロトコルは通信オーバーヘッド(データ量や送受信処理の負荷)が大きめですが、他言語とのやり取りや通信内容の確認を容易に行えます。バイナリベースのプロトコルは通信オーバーヘッドを抑えられますが、他言語とのやり取り(相手方がスクリプト系言語など)や通信内容の確認が面倒なことが多いです。


例えば、上記の例で、片方のPCが相方のPCに「自分のアプリが止まったらそっちで動作開始してね」と伝えたい

要件次第ですが、本当に単純な通信しか行わないのであれば、独自のメッセージフォーマット/通信プロトコルを定義してしまうというやり方もあります。ただし、将来的に拡張したくなったりすることを考えると、汎用性のあるプロトコルを採用してしまったほうが無難でしょう。

投稿2017/06/28 01:57

編集2017/06/28 02:00
yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sin_250

2017/06/28 12:16

ご回答ありがとうございます。なるほど、JSONなどは普段使っていますが、テキストベースで構造も入れ込めてライブラリもあるし、便利ですね。 MessagePackなども存じませんでした。ご教示頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問