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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TCP

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

解決済

C#とArduino(Due)を用いたTCP通信による文字列の送受信におけるサイズについて

masaroid
masaroid

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TCP

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2回答

0評価

1クリップ

6435閲覧

投稿2015/04/13 04:03

PC(C#)とArduino Due + Ethernet Shieldの構成で、TCP通信を用いてArduinoから文字列を受信するプログラムを作成しました。

手順は以下の通りです。

  1. Arduino側で要素数4097(内1要素は終端null)のchar型配列sendMsgを定義し、4096要素に適当な文字を格納して送信
  2. C#で文字列を受け取り、0~4095まで1文字ずつ表示する

上記を実行すると、以下のような問題が発生しました。
・C#側では0~2047要素しか受信できず、2048要素目を表示しようとして、例外(IndexOutOfRangeException)が発生する

コアとなるソースコードは以下の通りです。ただし、コネクションの確立は既に行われているものとします。

Arduinoによる文字列の送信

lang

/* Arduino Language */ char sendMsg[4097]; EthernetClient client; ・・・ client.print(sendMsg); //serverとの接続は行われ、sendMsgには適当な文字が0~4095要素に格納されているものとする

C#による文字列の受信

lang

/* ns:接続先とデータの通信を行うためのNetworkStreamクラスのインスタンス resBytes:受信データを格納するためのbyte型配列(要素数4097) ms:受信データを蓄積するためのMemoryStreamクラスのインスタンス ad_buf:受信データを文字列として格納するための変数 enc:UTF-8形式のエンコーディング */ /* データ受信部の処理 */ do { int resSize = ns.Read(resBytes, 0, resBytes.Length); if(resSize == 0) { break; } ms.Write(resBytes, 0, resSize); }while(ns.DataAvailable); ad_buf = enc.GetString(ms.ToArray()); ms.SetLength(0); Thread.Sleep(100); for(int i=0; i<4096; i++) { Console.WriteLine("{0}:{1}", i, ad_buf[i]); //2048要素目の出力で例外処理が発生する }

原因特定を速める目的で、重要となる部分以外をかなり省略させて頂きました。

理想的には0~4095要素の文字を受信し、1文字ずつ表示するようにしたいのですが、上記のプログラムを実行すると2047文字までしか受信できず、それ以降の文字を取得することができないと言った問題が発生しました。

このような問題が発生する原因とその対処法をご教授頂くべく、今回質問させて頂きました。

必要な情報が落ちているという指摘があった場合、追って載せさせて頂きます。

ご回答の程、宜しくお願い致します。


念のため、通信を行う各端末のスペックを記載します。

PC
型:Let'snote CF-S10
OS:Windows7 Professional 64bit
CPU:Corei5 2540M 2.6GHz
メモリ:4GB
詳細の仕様
http://panasonic.biz/pc/doc/catalist/pdf/S10E.pdf

Arduino Due
MCU:AT91SAM3X8E(Cortex-M3)
Clock:84MHz
Flash Memory:512KB
SRAM:96KB
詳細の仕様
http://arduino.cc/en/Main/arduinoBoardDue

Arduino Ethernet Shield
詳細の仕様
http://arduino.cc/en/Main/ArduinoEthernetShield

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

lichten

2015/04/14 08:37

wakuwakuさんが指摘している問題が一番重要ですが、問題になるインデックスが想定のピタリ半分というのも気になりますね。 おそらくASCIIコードしか入っていないUTF-8だから、文字数=バイト数、という見込みでプログラムを書かれているのだと思います。 しかし仮に、1文字で複数バイト使用する文字が入ると問題になるコードになっています。 ms.ToArray() の結果を、そのまま1バイト毎に出力すると何かわかるかもしれません。
masaroid

2015/04/14 14:57

解決のご提案ありがとうございます。 lichtenさんの仰る通りで、送信する文字は1文字1バイトの文字のみを想定しているため、上記のような記述と致しました。 インデックスが想定の半分になるというご指摘を受け、Arduino側で送信するデータサイズを倍の8192byteに変えてみたところ、C#側で受信できたデータサイズは変わらず2048byteという結果になりました。 ms.ToArray()の結果を1文字ずつ読み込んだ場合は、0~2047の要素で送信した時の文字と完全に一致することを確認しました。 こうなると、根本的に送信側で2048byteしか送信できていない可能性も考えられます。 引続き、原因を究明して行きたいと思います。
wakuwaku

2015/04/14 22:20

PC側でパケット監視ツール(wiresharkなど)を使って 届いているが受信できないのか そもそも届いていないのか を調べてみるといいかもしれませんね。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

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

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TCP

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。