TCPでファイルを送受信する ~ファイル転送アプリを作った話~

どうも!洋梨🍐です。

先日、祖父の家に行ったところスマホで撮った写真を印刷していたのですが様子を見たところ、スマホから毎回microSDを取り外し、パソコンで印刷してました。

それがどうも面倒なようで楽にしてあげようと思い、画像を簡単に(無線で)PCに転送できるようなアプリを開発することにしました。

仕様

今回は送受信にTCPを使い、ポートは23230を使いました。番号に意味はありません。

なお、即席(2,3時間ほど?)で作ったためエラー処理とかその他もろもろしていません👼

作成・動作環境

受信側はWindowsでの使用になるので.NET Frameworkでの開発。

送信側はAndroidでの使用になるのでXamarin.Formでの開発です。

※動作確認はWindows10+Android(自分のP20Lite等、祖父のらくらくスマートフォン)で行いました👼

パケット構造

送受信に使うパケットの構造はこんな感じに今回は考えました

ファイル名はUTF-8でバイト列に変換し、メインのファイルデーターのバイト列を1 Byte(0xFF)で仕切った構造となってます。

このパケットを送信すれば受信したバイト配列から元のファイル(画像)の復元ができそうです。

送受信の流れ

1・受信側:ファイルの受信を受け付けるためにポート(TCP:23230)監視を開始する

2・送信側:ファイルをユーザーに選択してもらう

3・送信側:選択したファイルを読み取り、独自パケットに変換する

4・送信側:変換したパケットをTCPで送信

5・受信側:受信した独自フォーマットのパケットを変換・ファイルに書き出し

といった流れです。

送信側の処理

まずは送信側の処理についてです。送信側が主にすることは

・ファイルの読み込み
・独自パケットへの変換
・パケットの送信

です。では順を追って説明していきます。

ファイルの読み込み

まずユーザーにスマホで送りたいファイルを選んでもらいます。

そのために画像ピッカーを開き、選択されたファイルのURIを取得し、URIを使いStreamを取得します。

まずGetStreamByPicker()で画像ピッカーを起動します。起動方法はintentのTypeに”image/*“を指定し、複数選択を許可するためにExtraAllowMultipleをtrueにしました。

選択後、ActivityHost.OnResult(uris)が呼び出され、GetStreamByURI()で取得したUriからファイルのStreamに変換しています。

独自パケットへ変換

先ほどのStreamからデーターのバイト配列を取得し、それを引数(baseByte)にし独自パケットのバイト配列に変換します。

データーのByte配列の先頭にファイル名(UTF-8)をByte配列にし、先頭に追加し0xFFで区切るだけといったシンプルなものです。

パケットの送信

ただただTCPでストリームに流して送信するだけです。

受信側の処理

受信側はそんなに難しくありません。

・TCPポートを監視する。
・パケットを受信する。
・パケットを変換・保存する。

といった流れです。

await tcpListener.AcceptTcpClientAsync();で接続を待機しています。

接続後NetworkStreamでデーターを受信し、MemoryStreamに一度書き出します。なお、mStream.GetBuffer()のByte配列のデーターをそのまま使うと最後が0x00の余分なデーターがついてしまうので注意です。

こんな感じでパケットを受け取った後はパケットを名前とデーターに分けます。

こんな感じでファイル名とデーターに分けます。そして、データーの部分をFileStreamで保存します。コードは

このようになります。

実行の様子

受信側(Windows10):Windows.Form
送信側(Android) : Xamarin.Form

※ちなみに認証等セキュリティー面などは全く配慮されてませんので紹介するソースコードをそのまま使って公開するアプリを作ったら終わります。


ここまで読んでくれてありがとうございました!!

ホームページでは他にも

・様々な記事や作った作品および過程
・ソースコード、素材ファイル
・あらゆる”モノ”の作り方

などなど随時、記事や作品を新規公開・更新していますので是非見ていってくださいね!見ていただけると本当に嬉しいです!

Xamarin.Formでタッチイベントを取得した時の話

先日、Xamarinでアプリ開発をしていたとき「タッチイベント」を取得したかったのですが、少し難しい部分だったのでメモとして書き残しておきます。

今回紹介する取得方法は「タッチイベント」はクリックしたという情報だけでなく、タッチを始めた・続けている・離したといったような動作及びタッチした座標といったプラットフォーム別に取得できるような情報の取得する手段になります。

タッチした、長押ししたといった単純動作にはこの手段を使わず、OnClickイベントを使うことをお勧めします。

取得の仕方

取得した情報を入れるクラスを定義する

タッチされた指の識別番号を入れるためのid(long)、タッチイベントの種類を入れるためのtype(TouchEventType)、座標情報を入れるためのPos(Forms.Vec2)を定義しました。

デリゲートを定義する

Xamlから呼び出し用:エフェクトを定義する

Android用

このようなクラスをAndroid環境に追加します。

※iosはビルド環境がないので書きませんがGoogle上にあるのはiosの方が多いはずなのでそちらを参考にしてください~

使い方

Xaml上で使う方法

例:SkiaCanvas(SKView)上のタッチ座標を取得したいとき

これでOnTouch(object obj, TouchEventArgs args)が呼ばれます。

今回は同じnamespaceに書いてしまってますが、使用するときは別にしたほうがいいと思います👼

著者の一言

このホームページを始めて3か月が過ぎました(現在)。閲覧者の年齢層
が気になったのでアンケートで確認したところ同年代(大学生)の方より30,40代の方が多かったというのもあり久しぶりにちょっと専門的な事を書き始めようかななんて思った今日この頃です。


ここまで読んでくれてありがとうございました!!

ホームページでは他にも

・様々な記事や作った作品および過程
・ソースコード、素材ファイル
・あらゆる”モノ”の作り方

などなど随時、記事や作品を新規公開・更新していますので是非見ていってくださいね!見ていただけると本当に嬉しいです!

【C#】独自クラスをXML形式で保存する

こんちゃ!洋梨🍐です。

今回はアプリ内でデーターを保存するときにXML形式を用いた時の手順及びソースコードをメモとして書きたいと思います。

XML形式のファイルを読み取る

ソースコード・XMLFinder.cs

この一応ソースコードのほとんどは使わない部分だと思いますが、とりあえず取得するときはGet_Kvp()を使ってキーと値のセットを取得できます(一応)。また、その値をもとに再検索し入れ子に対応させるという使い方も一応できます。

XML形式で保存する

XML形式に保存するにはただ<>で囲み、</>で閉じるだけです。

ソースコード(一部)

XML・独自クラス間の変換を行う

XFile_Converter.cs

このXFile<T>クラスを用いることによりXML、独自クラスでの双方変換が可能になります。

使い方

上記スクリプトを使った使い方を簡単に説明します。

まずこのような独自クラスがあったとします。

このUserDATA配列をXMLに変換したい場合

このようにします。逆に戻したいときは

このようにします。

なお、XML形式で保存する方法を紹介と言いながらクラス内のデーターはコンマで区切ってます^^

こんな感じです

この保存方法のメリットはXMLのタグを検索すればそのクラスの配列を取得できます。

つまり今回UserDataを”P”というタグで保存した為、UserDataを取得したいときはPタグを取得すればよく、追加したらそのタグを検索すればいいといった感じです。

また、可読性も上がるかなと思いXMLで実装してみたというのもあります👼


ここまで読んでくれてありがとうございました!!

ホームページでは他にも

・様々な記事や作った作品および過程
・ソースコード、素材ファイル
・あらゆる”モノ”の作り方

などなど随時、記事や作品を新規公開・更新していますので是非見ていってくださいね!見ていただけると本当に嬉しいです!