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

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

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

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

TCP

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

Q&A

解決済

2回答

1957閲覧

Python server, UWP(C#)client間でTCP通信がしたい

xsmiledur

総合スコア8

UWP

UWPは、Universal Windows Platformの略。様々なデバイス向けに提供されているアプリケーションを共通のフレームワーク上で動作可能にする仕組みで、Windows10で導入されました。

C#

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

TCP

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

0グッド

0クリップ

投稿2018/06/11 16:44

前提・実現したいこと

Pythonをサーバー,C#で書かれたUWPアプリケーションをクライアントとして,TCP通信で
Python→UWPにByte列(bytes)を送りたいです.
(画像の全画素値を送る目的で)

コードは
using Windows.Networking;
using Windows.Networking.Sockets;
Stream, StreamSocket, StreamWriter/ StreamReader
を使用して書いています.

C#→Pythonのbyte列送信はできています.
Python→C#ができないのです.

該当のソースコード

C#

1using Windows.Networking; 2using Windows.Networking.Sockets; 3#endif 4 5public class TcpNetworkClientManager 6{ 7#if WINDOWS_UWP 8 private StreamWriter writer = null; 9 private StreamReader reader = null; 10 private Stream st; 11 private StreamSocket socket; 12 13#endif 14 private int len = 0; 15 public byte[] read_output; 16 public byte[] read_output_ASCII; 17 public byte[] read_output_UTF8; 18 public byte[] read_output_Unicode; 19 public byte[] read_output_BigEudianUnicode; 20 public string read_string; 21 public string read_string_sjis; 22 public string read_string2; 23 public int read_int; 24 public bool isReadable = false; 25 public bool isStart = false; 26 public Encoding encode; 27 28 // データをReceiveしたかを確認する関数 29 public bool CheckReadable() 30 { 31 if (isReadable == true) 32 { 33 isReadable = false; 34 return true; 35 } 36 else return false; 37 } 38 39 40 // Start()関数内でnew TcpNetworkClientManager(...)として使う 41 public TcpNetworkClientManager(string IP, int port) 42 { 43#if WINDOWS_UWP 44 Debug.Log("Tcp Newtork Client Manager Start"); 45 Task.Run(async () => 46 { 47 socket = new StreamSocket(); 48 await socket.ConnectAsync(new HostName(IP), port.ToString()); 49 50 st = socket.OutputStream.AsStreamForWrite(); 51 writer = new StreamWriter(st); 52 Debug.Log("writer created"); 53 isStart = true; 54 }); 55#endif 56 } 57 58 // 成功 59 public void SendData(byte[] data) 60 { 61#if WINDOWS_UWP 62 if (writer != null) Task.Run(async () => 63 { 64 len = data.Length; 65 writer.BaseStream.Write(data, 0, len); 66 await writer.FlushAsync(); 67 }); 68#endif 69 } 70 71 // 失敗する 72 public void RecieveData() 73 { 74#if WINDOWS_UWP 75 List<byte> list_ = new List<byte>(); 76 read_output = new byte[len]; 77 78 79 Debug.Log("Receive Data Start"); 80 81 Task.Run(async () => 82 { 83 84 // Read data from the echo server. 85 string response; 86 string received = ""; 87 char[] buf = new char[len]; 88 int x = -1; 89 using (Stream inputStream = socket.InputStream.AsStreamForRead()) 90 { 91 using (StreamReader streamReader = new StreamReader(inputStream)) 92 { 93 // encode = streamReader.CurrentEncoding; 94 // await streamReader.BaseStream.ReadAsync(read_output, 0, 1); // byte列を読み込む関数なのにうまくいかない.止まる.Readが終わらないみたい 95 // stringに代入する方法はあるが,byte列を実体の不明なstringに代入したところでうまくかない 96 response = await streamReader.ReadToEndAsync(); // 向こうが送ったのちにsocketを閉じたらいける. 97 } 98 } 99 100 // 外から読み取れるpublic変数に代入 101 read_int = x; 102 read_string = response; 103 104 // 以下,stringを色んなエンコードでbyte列に変えることをしているが,どれも中身が送り元の中身と違っている 105 //read_output_ASCII = System.Text.Encoding.ASCII.GetBytes(read_string); 106 //read_output_UTF8 = System.Text.Encoding.UTF8.GetBytes(read_string); 107 //read_output_Unicode = System.Text.Encoding.Unicode.GetBytes(read_string); 108 //read_output_BigEudianUnicode = System.Text.Encoding.BigEndianUnicode.GetBytes(read_string); 109 isReadable = true; 110 }); 111 Debug.Log("Receive Data End"); 112#else 113 byte[] output = new byte[0]; 114 //return output; 115#endif 116 117 118 } 119} 120

Python

1import socket 2import time 3from contextlib import closing 4import fast_style_change as fsc 5import numpy as np 6 7def main(): 8 host = "192.168.0.4" #お使いのサーバーのホスト名を入れます 9 port = 4000 #クライアントと同じPORTをしてあげます 10 11 # 画像の行・列の大きさ 12 dst_rows = 300 13 dst_cols = 300 14 15 serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 16 serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 17 serversock.bind((host,port)) #IPとPORTを指定してバインドします 18 serversock.listen(10) #接続の待ち受けをします(キューの最大数を指定) 19 20 print('Waiting for connections...') 21 clientsock, client_address = serversock.accept() #接続されればデータを格納 22 print("Succeeded in Connection!") 23 24 while True: 25 crop = clientsock.recv(3 * dst_rows * dst_cols) 26 img = np.frombuffer(crop, np.uint8, -1) # ここで正しく読みとれているのは確認済み 27 28 img_reshape = img.reshape(dst_rows, dst_cols, 3) 29 output = fsc.stylize(img_reshape, 2, str(time.ctime()).replace(' ', '_').replace(':', '_') + "output.jpg", False) # ここも正しく処理できているのは確認済み 30 31 # ここでC#に送るとC#側でうまく読みとれない 32 clientsock.sendall(output.tobytes()) 33 # print(np.frombuffer(output.tobytes(), np.uint8, -1) # 正しく復元するので.tobyte()のバイト列変換も正しいとわかる 34 break 35 36 clientsock.close() 37 38if __name__ == '__main__': 39 main() 40

試したこと

C#内で受け取るデータはstringとなるが,そのstringに対して色んなエンコーディングでbyte列に変換した.しかし,いずれも長さや中身の要素が送り元と異なっていた.

そもそもstringではなくbyte列で受け取る方がいいと思うのだが,そういう関数を使ったりすると計算が止まったりして進まなくなる.

StreamSocketではなく普通のSocket等でもいいのかもしれないが,
UWPで使えるSocket通信APIと検索してこれがヒットしたので使っているため,
SocketがUWPで使えるのかはそもそも不明です

教えていただけると幸いです.

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

Python 3.6
Unity 2017.3.1f からビルドしたUWPアプリケーション
.NETは多分4.*とかです

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

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

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

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

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

guest

回答2

0

Socketでゴリゴリ書きたがる人が多いですが。デバックが結構大変ですよ。。
WireSharkを導入して実際のパケットを確認してみることをお勧めします。

個人的には通信頻度の問題はありますが、HTTPまたはWebSocketでやり取りすることをお勧めしています。

C#側 HttpClientクラスを使用
Python側 http.serverもしくはWebフレームワークを使用。

投稿2018/06/11 17:46

編集2018/06/11 17:46
umyu

総合スコア5846

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

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

0

自己解決

結局BinaryRead(Stream)を使って解決しました.
DatagramSocketのUDP通信でそう書いてるコードを見かけて,同じ手筈でバイナリ受信ができました.
次回HTTP通信も試してみようと思います.ご回答ありがとうございました.

投稿2018/06/15 03:00

xsmiledur

総合スコア8

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問