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/*“を指定し、複数選択を許可するためにExtraAllowMultipletrueにしました。

選択後、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

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


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

ホームページでは他にも

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

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

あわせて読みたい