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

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

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

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

Q&A

解決済

2回答

5994閲覧

C# ソケット通信 配列の取得

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

1クリップ

投稿2017/05/17 06:44

C# ソケット通信で配列を送る方法

サーバー側にstring[] aに"あいうえお" "かきくけこ"・・・が入っている場合、

byte[] SendBuffer = Encoding.Unicode.GetBytes(StringList[0]);
stream.Write(SendBuffer, 0, SendBuffer.Length);

で送りたいのですが、これだとインデックス番号が0だから"あいうえお"しか送れないですよね。

ここで質問なのですが、インデックス番号が100まである場合、どうすればよいのでしょうか?
よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

出発点が間違ってるーかなー。

以下みたいに送りたいデータ毎に送信するためのコード、っていうのは書きません。

byte[] SendBuffer = Encoding.Unicode.GetBytes(StringList[0]); stream.Write(SendBuffer, 0, SendBuffer.Length);

理想は以下のような関係を構築することです。

Send(object obj) { // .. byte[] bytes = Serializer.Serialize(obj); stream.Write(SendBuffer, 0, SendBuffer.Length); // .. } T Receive<T>() { bytes[] received = // return Serializer.Deserialize<T>(received); }

ものを入れれば送れる、その汎用的な手段を構築する必要があります。
貴方はたぶん、「文字列」を送る方法を知っているから最初の質問にたどり着いています。
しかし、「オブジェクト」を送る方法を知らないので、文字列の配列…の他の問題になった時も今のままだと作業が止まってしまうでしょう。

では、オブジェクトを送るにはどうすればいいでしょうか。
それは、オブジェクトを文字列やバイト配列など、ストリーム送信可能な形に変換することです。
この変換を「シリアライズ」と言います。
こうした伝送プログラムは、大体の場合目的に合致するシリアライザを検討するところから始まります。

シリアライザは文字列へのシリアライズでも、byte配列へのシリアライズでもどちらでもいいです。
Json.NET(Newtonsoft.Json)で一旦jsonに変換をかけることでオブジェクトを文字列にできます。
これを最初の方法で文字列として伝送することができます。
以下はJson.NETで配列のシリアライズ、デシリアライズの最小サンプルです。

object array = new string[] { "test1", "test2", "test3" }; string serialized = JsonConvert.SerializeObject(array); string[] deserialized = JsonConvert.DeserializeObject<string[]>(serialized); foreach(var str in deserialized) { Console.WriteLine(str); }

見て頂けばわかるように、一旦1つの文字列にされたものが、string[]に戻っています。
これを最初に言った形で関数化すると、以下のようになります。

C#

1Send(object obj) 2{ 3 var serialized = JsonConvert.SerializeObject(obj); 4 5 // .. 6 byte[] SendBuffer = Encoding.UTF8.GetBytes(serialized); 7 stream.Write(SendBuffer, 0, SendBuffer.Length); 8 // .. 9} 10 11T Received<T>() 12{ 13 bytes[] received = // 14 15 var json = Encoding.UTF8.ToString(received); 16 return JsonConvert.DeserializeObject<T>(json); 17}

で、以下のように使う…と。

C#

1string[] valueWantToSend; 2Send(valueWantToSend); 3 4var wantedToReceive = Receive<string[]>();

シリアライザは他にも沢山あります。
例えば、protobuf-netという直接byte配列にシリアライズしてくれるものもあります。
これはjsonと比べると、もっとずっとコンパクトにデータをシリアライズしてくれます。
配列やDictionaryにも対応しています。

各シリアライザには思想があり、できること、できないことがあります。

通常、サイズにピーキーな案件でもシリアライザは既製品を使うことが多いです。
内製しても著名なシリアライザを超える性能を出しつつ、汎用に動作させることはなかなか難しいからです。

とりあえずは、シリアライザを調べてください。

投稿2017/05/17 08:27

編集2017/05/17 08:44
haru666

総合スコア1591

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

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

退会済みユーザー

退会済みユーザー

2017/05/19 06:23

素早いご回答ありがとうございました。 もっと勉強を頑張って理解できるようになります!
guest

0

単純にやるなら、インデックス番号を1、2、、、100と順に変えていって送れば良いのでは?

何が正しいのかは、受信する側が、どのように送って欲しいのかによります。
"あいうえお,かきくけこ,さしすせそ,・・・"のように一纏めで受信したいのなら、101回に分けて送るのは適切ではないですからね。

受信側がどのように送信される事を望んでいるのかを質問に明記すると、良い回答が得られると思います。

投稿2017/05/17 07:40

coco_bauer

総合スコア6915

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問