この質問を見ていただきましてありがとうございます。
当方、C言語の基本がわかるレベルのものです。
調べてみたのですが、結果にたどりつかなかったので質問させていただきます。
早速掲題の件です。
やりたいこと
マスターのパソコンから信号(数値の情報)を複数のPCに送りたい。
具体的には、複数のPCで動いているメインソフトから
今回作成したいプログラムを呼び出し、マスターから送られている
指令値を読み取ってそれに従いメインのプログラムが動くというものです。
なので、マスター側の送受信プログラムとスレーブ側の送受信プログラムが必要なのかなと思います。
出す指令値はすべてのPCに対しては共通です。
できれば、設定が完了したかというマスターへのリターンは受信側から欲しいです。
このメインのソフトでは通信のやり取りができないので、外部のソフトを動かして
情報を取得したい。
また、もし可能であればマスターからリクエストがあった場合、情報を返すということもしたいので
双方向のやり取りができるようにしたいです。
ここで質問なのですが、
1.そもそもVisual studioでこのようなプログラムは作成可能でしょうか?
2.このようなプログラムを作成する場合、Visual studio以外のほうが向いているのでしょうか
3.これを作成するにあたり、おすすめの参考書はありますか
4.似たような事例はありますか?
以上になります。
説明不足などわかりにくい部分があったら申し訳ございません。
質問等は早めに返します。
ご協力の程よろしくお願いいたします。
補足です。
上記の図のように、マスターからスレーブのPCへ送信して
スレーブ側は受け取った値をスレーブ側のプログラムに渡したいです。
可能であれば、設定を完了したというアンサーをマスター側へ返したいです。
送信項目は一例です。難しいことは送らないで、
簡単に送ろうと思っています。
もし可能であれば、個別に送信もしたいです。
umyu様のご回答を踏まえて作成してみました。
正直、理解しきれていない箇所もありますが記載しています。
http~部分など。
まずは、仕組みを理解する必要もあるかもしれません。
追加2017.11.14
更新が遅くなってしまい申し訳ございません。
ルーターの設定の件などに関して先にご回答させていただきます。
ルーター等のネットワークなどの構成自体は変更は難しいということでした。
理由としては、
自社のルーターを超えて、行くわけですが操作したいスレーブ側のPCでは
一般的なPCの他に、レンタルサーバーを、利用してその中でメインのソフトを動かしているのものあるためです。
その他色々と方向性が見えた部分がありました。
後ほど、早ければ今晩にでも更新させていただきます。
何卒よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/11/07 03:32

回答3件
0
Websocketなどのライブラリを使うのが一番手っ取り早く実装できると思います。
cだとメモリ管理が煩雑になるので、c++で実装したほうが実装コストは下がると思います。
業務でよく使うのはSocket.ioです。
https://github.com/socketio/socket.io-client-cpp
もちろんC言語の基本が分かる程度というお話なので無理にとは言いませんが、知識としてあるといいかと思います。
通信系の実装をSocketなどで手で実装してみるのも勉強になるので色々試してみるといいと思います。
投稿2017/11/13 05:21
総合スコア49
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
ベストアンサー
1,そもそもVisual studioでこのようなプログラムは作成可能でしょうか?
はい。可能です。
確認したいポイントが5点あります。
1,送りたいデータに関して
1-1,信号はロス(欠損)しても、大丈夫なデータなのでしょうか?
1-2,制御コードは送信データに含まれますか?
1-3,データ量と頻度はどれくらいの間隔ですか?
2,開発する期間はどれくらいを想定してますか?
3,送信側PCと受信側PCはルーターを超えますか?
◆案1,HTTPプロトコルを流用して、簡易webサーバーと独自仕様の通信プログラムを作成することです。(筆者お勧め)
理由:通信プログラムをテスト/デバックする必要があるのですが、
httpプロトコルベースだとブラウザの開発者ツールやフリーソフトがあるので、テストツールの作成負荷が軽減されます。
.netなら
System.Net.HttpListenerが使用できます。
◆案2,ネットワーク共有フォルダを各PCに作成して、ファイルコピー&ファイル受信監視ソフトを使って通信する。
問題点:開発は案1と比較して開発難易度が低いですが、ルータやFWに通信が制限される事が多い事と、共有フォルダのアクセス権限の問題が発生します。
開発するに当たっては、まず送信側PCと受信側PCの状態遷移図を記述しながら、通信プロトコルを設計したほうが手戻りが少ないと思います。
コメント欄への返信に追記です。
Webサーバーを作成して情報をあげて、そこから情報を取得するという感じでしょうか?
はい、簡易的なwebサーバーをSystem.Net.HttpListenerで作成です。
1,スレイブ側はマスターからの受信を送受信ソフトで受信待機。(listen)
2,マスターは信号を契機にスレイブ側にPOST/GET要求。
参考までに信号送信とスレイブ1側の情報要求の簡易的なイメージ図を添付します。
◆信号送信
メソッド:POST
URL:http://スレイブ1:送受信ソフトのポート番号/control
データ:信号(起動/終了、スタート/ストップ)、プロトコルバージョン※1
※1
プロトコルバージョンはurlに含める形でも良いと思います。
◆情報要求
メソッド:GET
URL:http://スレイブ1:送受信ソフトのポート番号/information
データ:なし
状態遷移図に含めたい物としては例えば
1,信号:起動が未送信状態の時に信号:スタート/ストップがスレイブ側に間違って送られた時にどう対応したいのか?
2,スレイブ側のPCが電源断/再起動などでスレーブ側のメインのプログラムがシャットダウンした時のリカバリー方法
があります。
マスターの送受信ソフトは最初はブラウザまたPowerShellで代用できるので開発優先順位としては低いです。
2017/11/06の追記2です
てっきり送受信ソフト<->スレイブ側のメインソフトのインターフェイス要件(起動/通信方法及びパラメータ)は決まっていると思ってました・・・。
まずはメインソフトの作成者の方またはメインソフトの仕様に詳しい人と話し合って
送受信ソフト<->スレイブ側のメインソフト間の大まかなインターフェイス要件を詰めたほうがいいのではないかと。
最低限確認しないといけないことは以下の6点でしょうか
1,送受信ソフトからメインソフトへの信号(起動、終了、スタート、ストップ)、状態問い合わせの送り方とメインソフト側での検知方法。
2,送受信ソフトからの信号をメインソフトで処理したという結果(信号の処理にもしも時間が掛かるなら、その場合はどうするのか)をメインソフトから送受信ソフトへどうやって返す予定なのか。
3,送受信ソフトからスレイブ側のメインソフトに信号を送ってはダメなタイミングは存在するのか?(例えばメインソフトで何らかの処理を処理継続中の時など)
→これがあると結構大変になります。。。
4,信号:起動を送った時のメインソフトを起動する時の起動パラメータ。(あれば)
5,疎通テスト環境の作り方。
6,パラメータのフォーマット。(フォーマットにはプロトコルバージョン(上図のとは別)があるのが理想ですが、ココらへんは作成者の好みによるかと。。)
これとは別にマスターのパソコンから信号を送るタイミングに付いても、関係者への周知事項として必要になる事が多いため予め決めておく必要があります。
(定期的/臨時)でこの時間/このタイミングでこの信号をスレイブに送るという情報
話題が逸れてしまったので戻します、以下は質問の回答です。
1.指定したソフトが起動しているか判別かのうか
スレイブ側の送受信ソフトで判断する事が可能です。
ゆるい判定…System.Diagnostics.Process.GetProcessesByName
厳密な判定…System.Threading.Mutex
→二重起動防止方法でぐぐると参考情報が出てくるかと。
2.スレーブの送受信ソフトから指定されたソフトを起動可能か
ProcessInfo#Start()でソフトの起動が行えます。
送受信ソフトとユーザーが同じになる点が注意点でしょうか。
3.マスター側からスレーブのソフトを起動することは可能か
こちらは上の2に関連しますが、スレイブ側PCのスタートアップに送受信ソフトを入れておけば、
スレイブのPCが再起動しログイン※1したタイミングでマスター側の信号送信を契機にスレイブ側のソフトを起動できます。
※1 これが嫌な時はWindowsサービスを作成する必要がありますが、難易度が高くなります。私も回答できる範囲を超えてるので、再度要件を纏めて、msdnフォーラムやstackoverflowで聞いてみるのもいいかもしれません。
※注意点として、マスター側から定期的に問い合わせ(ポーリング)をしないといけなくなりますが。
電源断/再起動に関してはシステム管理/運用部があればそちらの方で、検知してるのではないかと。
追記3
Visual studioのC#言語&WPFで作ったスレイブ側の送受信ソフトのサンプルソースへのGitHubリンクを貼っておきます。
あくまでもこんな感じというサンプルです本来必要なエラー処理が大量に抜けています、あまり流用しないでください。
Visual studioでサーバー側のデバック実行とブラウザの開発者ツールでネットワークログを見ながら、ダミークライアント(control_test.html、information_test.html)を使ってみてください。
2017/11/15追記4
ルータ側の設定を変更出来ない場合は、httpやhttps以外のポート番号だとファイアウォールでフィルタリングされる可能性がありますが。
通信ソフトの大前提として、スレイブ側は任意のポート番号で通信の受信待機をする必要があるという認識を持ってくださいな。
3分間ネットワークの第43回レイヤ4 ポート番号の説明
1./controlと/informationに関してなのですが、
この中にあるアドレスの「127.0.0.1:6556」の部分はどうやってきめているのでしょうか?
TCP/IPは1:1通信なため相手先のIPアドレスとポート番号が必ず必要です。
127.0.0.1:6556→まず127.0.0.1は自分自身を表すループバックアドレスです、そしてポート番号:6556です。
これは質問文だとスレイブ1~4のPCのIPアドレスになり、スレイブ側でサーバーが使っていないポート番号を質問者が決める必要があります。
2./controlで、信号という項目がございますが、これはどういった風に使うのでしょうか?
元々の質問として、スレイブ側に信号情報(スタート、ストップ、起動、終了)を送りたいという質問ではなかったのですかー?
スレイブ側に伝える情報として、信号情報が必要です。
そして、送信側(マスタ側の送信ソフト)が信号の取りうる値を定義(例えば、スタートは値:1,ストップは値2など)して、それをスレイブ側に伝える必要があります。
受信待機しているスレイブ側は送られてきた信号値を元に処理を行う必要があります。
今回提案したのはデータとして信号情報を送るという形です。
3.上記2の質問と重なりますが、/informationの中で、信号のように取得したい情報を分けることは可能なのでしょうか?
ちょっと質問の意図が読めなかったのですが、
◆情報取得(/information)の時
1,マスター側から任意の送信データを送る。
2,スレイブ側は送られてきた送信データを元に処理を分岐したい
という質問で宜しいでしょうか?
/informationはメソッドがGETなので、クエリストリングになります。
HTTPとPOSTとGET
フォームデータを送信する
control_test.htmlと同じように
<input type="radio" name="data" value="001" checked>などをformタグ内に定義してみてください。
<input type="submit" value="送信">
入力フォームに入力した内容をサーバー(スレイブ側)に送信するボタンです、「<input type="submit" value="送信">」でキーワード検索してみてください。
4.この/conrolや/informationの部分は大きなくくりでなにか呼ばれ方などはあるのでしょうか?
キーワード「REST API」「RESTful API」「Web API」とかで検索してみてください。
一番最初の回答にも記載しましたが、要件と全体フローをはっきりと定義したほうがいいのではー。
どういう情報をどのタイミングで送信したいのか、どういう結果を受信したいのか。
マスターとスレイブはどういう状態がありえるのか。
投稿2017/11/04 12:34
編集2017/11/14 21:39総合スコア5846
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
C言語が わかる、Visual Studio が使えるという前提で・・・
UDP/IP 通信を利用して、ブロードキャストアドレスへの送信というものを行えば、1台のマシンから複数のマシンへ送信を行えます。
ブロードキャストアドレスと言うキーワードと
例題の関数を 調べると
おぼろげながらも わかってくるのではないかと思います。
実績のあるプログラムのうち基本的な部分だけ抜き書きしておきます。
抜き書きなので このまま 書いても コンパイルは通りませんので悪しからず。
C++
1// 初期化 2 3 WSADATA wsaData; 4 ret = WSAStartup(MAKEWORD(2,0), &wsaData); 5 6 if(0 != ret) 7 { 8 // エラー処理 9 } 10 11 // ソケットの作成 12 13 socket_ = ::socket(AF_INET, SOCK_DGRAM, 0); 14 15 if (socket_ == INVALID_SOCKET) 16 { 17 // エラー処理 18 } 19 20 21// 送信側 22 23 struct sockaddr_in addr_ = {}; 24 25 addr_.sin_family = AF_INET; 26 addr_.sin_port = htons(port); 27 addr_.sin_addr.S_un.S_addr = inet_addr(ipAddress); // ブロードキャストアドレスに送信 28 29 30 length = sendto(socket_, 送信用バッファ, sizeof(送信バイト数), 0, (struct sockaddr *)&addr_, sizeof(addr_)); 31 32 if(0 == length) 33 { 34 // エラー処理 35 } 36 37 38// 受信側 39 40 sockaddr_in localaddr ={}; 41 42 localaddr.sin_family = AF_INET; 43 localaddr.sin_port = htons(port); 44 localaddr.sin_addr.S_un.S_addr = INADDR_ANY; 45 46 // バインド 47 int status = ::bind(socket_, (sockaddr*)&localaddr, sizeof(sockaddr_in)); 48 if (status == SOCKET_ERROR) 49 { 50 // エラー処理 51 } 52 53 int size = sizeof(sockaddr_in); 54 55 int length = ::recvfrom(socket, 受信用バッファ, 受信最大バイト, 0, (sockaddr*) &localaddr, &size); 56 57 if (length == SOCKET_ERROR) 58 { 59 // エラー処理 60 } 61
投稿2017/11/02 07:42
総合スコア1648
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。