🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2802閲覧

ソケット通信を用いてリアルタイムでグラフを変化させたい

sk009

総合スコア0

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/22 07:31

編集2021/02/22 09:24

前提・実現したいこと

ソケット通信を用いてリアルタイムでグラフを変化させたい
現在,私はPC-RaspberryPi間におけるソケット通信プログラムを作成しております。作成したプログラムは,PCからRaspberryPiに数値情報を送り,RaspberryPi側で受け取った数値をグラフにリアルタイムで表示するというものです。
ソースコードは以下のようになっています。

しかし,このプログラムではRaspberryPi側は数値情報を1回しか受信できないため,グラフを途中で変化させることができません(図1のようにyの値が一定のグラフしか出力できない)。このプログラムを複数回の送受信ができるように改良し,グラフをリアルタイムで変化させるにはどうすれば良いでしょうか?(図2のようにyの値を変化させたい)

説明が下手で申し訳ありません。よろしくお願いいたします。(現在のプログラムでは1回しか送受信ができないため,図1のようなグラフしか出力できません。これをリアルタイムで複数回の送受信ができるようにし,図2のようなグラフを作成したいです。)

イメージ説明

PC側のソースコード(言語:C言語,開発環境:Visual Studio2017)

#include <winsock2.h> #include <windows.h> #include <stdio.h> #include <conio.h> #pragma warning(disable : 4996) WSADATA wsaData; struct sockaddr_in addr; int sockw; #define IP_ADD_TEMP "0.0.0."//IPアドレステンプレ(同じネットワーク下なら使える) #define PORT_TEMP 1234 //PORT番号設定(クライアント/サーバで必ず合わせる) int main() { char buf[40]; int n, i; char aaa[] = "127.0.0.1"; // winsock2の初期化 if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { puts("reset winsock failed"); return -1; } // Server に connect して COMMAND を送信する // ソケットの作成 sockw = socket(AF_INET, SOCK_STREAM, 0); if (sockw == INVALID_SOCKET) { puts("make socket failed"); return -1; } // IPアドレス作成(defineを使う場合) /* char ip_add[30] = IP_ADD_TEMP; strcat(ip_add, argv[1]); */ //IPアドレス作成(すべて打ち込み) char ip_add[30]; for (int i = 0; i < 30; i++) ip_add[i] = NULL; strcpy_s(ip_add, aaa); // 接続先指定用構造体の準備 addr.sin_family = AF_INET; addr.sin_port = htons(PORT_TEMP); addr.sin_addr.S_un.S_addr = inet_addr(ip_add); // サーバーに接続 if (connect(sockw, (struct sockaddr*)&addr, sizeof(addr))) { puts("connect failed"); return -1; } // RaspberryPiに数値情報を送る n = send(sockw, "50", strlen("50"), 0); if (n < 0) { puts("send failed"); return -1; } // サーバーからデータを受信 memset(buf, 0, 40); n = recv(sockw, buf, 40, 0); if (n < 0) { puts("recv failed"); return -1; } puts(buf); while (1) { if (kbhit() != 0) { break; } } // ソケットのクローズ closesocket(sockw); // winsock2 の終了処理 WSACleanup(); return 0; }

RaspberryPi側のソースコード(言語:Python)

#ソケット通信プログラム import socket host = "127.0.0.1" port = 1234 serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serversock.bind((host,port)) #IPとPORTを指定してバインドします serversock.listen(10) #接続の待ち受けをします(キューの最大数を指定) print('Waiting for connections...') clientsock, client_address = serversock.accept() #接続されればデータを格納 for i in range ( 1 ): rcvmsg = clientsock.recv(1024).decode() print('Received : %s' % (rcvmsg)) s_msg = "def" print('Send : %s' % s_msg) clientsock.sendall(s_msg.encode()) clientsock.close() #ここから下はグラフ表示プログラム import numpy as np from matplotlib import pyplot as plt import random plt.figure() #x軸の幅を100にする xlim = [0, 100] X, Y = [], [] while True: #画面をクリア plt.cla() Y.append(int(rcvmsg)) X.append(len(Y)) #xに100個以上格納されたら if len(X) > 100: xlim[0] += 1 xlim[1] += 1 plt.plot(X, Y) #x軸、y軸方向の表示範囲を設定 plt.ylim(-1, 100) plt.xlim(xlim[0], xlim[1]) #描写 plt.pause(0.1)

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

thkana

2021/02/22 08:10

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10239264345 とりあえず、マルチポストに対するルールがあるので対応よろしく。 https://teratail.com/help#posted-otherservice 「やむを得ず複数のサイトに質問を投稿された場合は、質問内容にマルチポストをする理由を書き、他のサイトの投稿へのリンクを貼ってください。また、解決した際には必ずteratail及びすべての投稿に解決した旨と、どのように解決したかを記載してください。」だそうです。
sk009

2021/02/22 08:28

thkana様 コメントありがとうございます。teratailのルールを把握しておらず,他サイトに同様の質問を掲載してしまいました。先ほど他サイトに投稿したものを削除させて頂きました。申し訳ありませんでした。
dodox86

2021/02/22 08:30

ソースファイルは余程の理由が無い限り質問文中にコードとして貼り付けましょう。そうでないと、質問を読む方々は他サイトを閲覧しなければならなくなるし、 今回の例ではGoogle Drive上の共有を解除したら本質問と回答の意義が無くなります。teratailの質問、回答は後々の技術情報となり得る(ことも目指しているはず)もので、そういったことは望まれていません。また、他サイトを閲覧しなければならない時点で嫌がられ、回答は離れがちになります。
sk009

2021/02/22 09:06

dodox86様 ご指摘ありがとうございます。質問内容を変更させていただきました。
guest

回答2

0

このプログラムを複数回の送受信ができるように改良し

なぜそう考えるのでしょう? 改良とか余計なことを考えずに、新しいプログラムを作ればよいのではないですか? 改良とか改造とかにあたってよくある話ですが、前のものに未練を持って使おうとすると労多くして益少し、となったりします。

今のプログラムも意図がよくわからないところもありますが、とにかく「一回通信して終わり」というプログラムなのですから、それにこだわらず送信側はひたすら送信を繰り返す、受信側は受信しては(コネクションを切らないまま)描画、受信しては描画...を繰り返すプログラムを作ってみてはいかがでしょう。

それと、基本的なところですが、TCP/IPの通信の単位は1byte(通信だとオクテットとか言ったほうがいいの?)です。送り側で何バイトかまとめて送ったからといって、それが受信側でまとまって受信できる、あるいは一回送った分だけがまとまって受信できるという保証はありません。"50"を何回か送ったら"5""05""0505"などと受信されないという保証はないのです。プログラムの動作タイミングとかでなんとなく"50"が受信できてしまって動いているように見えることもしばしばですが、それは不確かな通信です。データの送信毎にデリミタ(区切り記号)などを挿入し、受信側ではデリミタまでのデータをまとめてから処理する等の対策をとる必要があるでしょう。

投稿2021/02/22 08:29

thkana

総合スコア7703

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

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

0

VisualStudioをつかってるなら、ブレークポイントを設定することでそこで実行を止め、変数の中身を見ることができます。また、そこから1行づつ実行することができます。
こうやって、あなたのコードの動作を追いかけ、なぜ一回の受信しかできないのか、というのを理解しましょう。
そして、どうしたら複数回の受信ができるのかを考え、それを実装していくことです。

その方法がまったく思いつかない、というのであれば、
「C ソケット通信」とか「python ソケット通信」とかでぐぐって、でてきたものを一通り読みましょう。

投稿2021/02/22 07:41

y_waiwai

総合スコア88038

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問