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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

Q&A

解決済

1回答

6013閲覧

1台のPCを使用したソケット通信について

Masalu_Kudou

総合スコア91

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

0グッド

0クリップ

投稿2020/11/21 18:24

お世話になっております。
すみません、ソケット通信もC#もVisualStudioも素人ですが、是非アドバイスをお願いいたします。

下記のサイトのようなソケット通信を試してみたいと思っております。
ただし、PCは1台しかなく、仮想PCを入れるほどハイスペックでもないため、自身にデータを送信し、
自分だけで通信が簡潔するようなプログラムを作成したいと思っております。

■ 参考にしたサイト
WPFで非同期アプリ間通信アプリを作りました

しかし、現時点で以下のエラーが出ます。

■ エラー内容
error CS0111: 型 'MainWindow' は、'.ctor' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。

何かこのエラーを解消しつつ、1台のPCでソケット通信を実施する方法はないでしょうか?
もしソケット通信ができるなら新規でロジックを作成することも考えております。
もしお分かりになる方、アドバイスをお願いいたします。

MainWindow.xaml

1<Window x:Class="WpfApp4.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp4" 7 mc:Ignorable="d" 8 Title="Client" Height="160" Width="240"> 9 10 <Grid> 11 <TextBox VerticalContentAlignment="Center" 12 HorizontalContentAlignment="Center" 13 HorizontalAlignment="Left" 14 VerticalAlignment="Top" 15 Height="115" 16 Width="243" 17 FontSize="48" 18 Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"/> 19 <!-- TextをValueプロパティにBindingしているので、テキストボックスで値を変更すると 20 対応するValueプロパティが変更される。 21 UpdateSourceTrigger は PropertyChanged にしている。 22 こうすることで値を入力したタイミングで更新され、リアルタイムでClient側に値を送信できる --> 23 <TextBox x:Name="value" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Height="127" TextWrapping="Wrap" VerticalAlignment="Top" Width="229" FontSize="48" Text="{Binding Value}" Margin="325,0,0,0"/> 24 </Grid> 25</Window>

MainWindow.xaml.cs

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.Windows; 7using System.Windows.Controls; 8using System.Windows.Data; 9using System.Windows.Documents; 10using System.Windows.Input; 11using System.Windows.Media; 12using System.Windows.Media.Imaging; 13using System.Windows.Navigation; 14using System.Windows.Shapes; 15using System.ComponentModel; 16 17namespace WpfApp4 18{ 19 /// <summary> 20 /// Interaction logic for MainWindow.xaml 21 /// </summary> 22 public partial class MainWindow : Window 23 { 24 public MainWindow() 25 { 26 InitializeComponent(); 27 28 /// データコンテキストにServerValueを設定すると 29 /// XAML側でServerValueのプロパティをバインディング 30 /// できるようになる。バインディングは簡単に言うと 31 /// UIとオブジェクト間で値をリンクすることができる 32 /// 今回はValueプロパティをリンクしてテキストボックスと 33 /// あたりをリンクしているので、テキストボックスで 34 /// 値を変更すると、Valueプロパティも変化する。 35 this.DataContext = new ServerValue(); 36 } 37 } 38 39} 40public class ServerValue : INotifyPropertyChanged 41{ 42 public event PropertyChangedEventHandler PropertyChanged; 43 44 #region プロパティ 45 /// <summary> 46 /// 今回通信でやり取りするデータ部分 47 /// Getter / Setter を持つ 48 /// Setter で OnPropertyChangedを使うことで 49 /// UIに変化通知が送信され、UIの値が更新される 50 /// 今回の例ではServer再度はあまり意味がない 51 /// </summary> 52 private int _value; 53 public int Value 54 { 55 get 56 { 57 return _value; 58 } 59 60 set 61 { 62 _value = value; 63 OnPropertyChanged("Value"); 64 } 65 } 66 #endregion 67 68 #region コンストラクタ 69 public ServerValue() 70 { 71 Value = 0; 72 73 var ipAdd = System.Net.Dns.GetHostEntry("localhost").AddressList[0]; 74 75 listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 12301); 76 77 listener.Start(); 78 79 accept(); 80 } 81 #endregion 82 83 /// <summary> 84 /// TCPClientのコネクション要求を受け入れる 85 /// 受け入れるまで非同期で待つ 86 /// 受け入れると acceptClient に処理を渡す 87 /// </summary> 88 async void accept() 89 { 90 while (true) 91 { 92 var client = await listener.AcceptTcpClientAsync(); 93 94 acceptClient(client); 95 } 96 } 97 98 /// <summary> 99 /// コネクションが確率されたクライアントに対して 100 /// 要求が来るまで非同期で待つ。要求が来た場合、 101 /// 要求に応じた応答をする。 102 /// 応答をした後、再度要求が来るまで待つ。 103 /// </summary> 104 /// <param name="client"></param> 105 async void acceptClient(System.Net.Sockets.TcpClient client) 106 { 107 var ns = client.GetStream(); 108 109 // 受信データ受けるようの箱を用意 110 byte[] result_byte = new byte[256]; 111 112 do 113 { 114 // ネットワークストリームからデータが取れるまで待つ 115 int result_size = await ns.ReadAsync(result_byte, 0, result_byte.Length); 116 117 // サイズが0ならコネクションが切られたと判断し、クライアントをクローズ 118 // 上位レイアで再度コネクションが来るまで待つ 119 if (result_size == 0) 120 { 121 client.Close(); 122 return; 123 } 124 125 // なにがしかを受信したと判断しValueプロパティの値を文字列にして返す 126 var enc = System.Text.Encoding.UTF8; 127 var send_bytes = enc.GetBytes(Value.ToString()); // 送信する用の箱にデータを詰める 128 ns.Write(send_bytes, 0, send_bytes.Length); 129 130 } while (ns.DataAvailable); 131 132 // 再度受信待ち状態にするために再帰呼出し 133 acceptClient(client); 134 } 135 136 private System.Net.Sockets.TcpListener listener; 137 138 /// <summary> 139 /// 値が更新されたことをUIに伝えるためのメソッド 140 /// name で指定されたプロパティが更新されたことを伝える。 141 /// </summary> 142 /// <param name="name"></param> 143 private void OnPropertyChanged(string name) 144 { 145 if (PropertyChanged != null) 146 { 147 PropertyChanged(this, new PropertyChangedEventArgs(name)); 148 } 149 } 150} 151namespace AppsCommunicationClient 152{ 153 public partial class MainWindow : Window 154 { 155 public MainWindow() 156 { 157 158 this.DataContext = new Client(); 159 } 160 } 161 162 public class Client : INotifyPropertyChanged 163 { 164 public System.Net.Sockets.NetworkStream Stream { get; set; } 165 166 private int _value; 167 168 public int Value 169 { 170 get 171 { 172 return _value; 173 } 174 175 set 176 { 177 _value = value; 178 OnPropertyChanged("Value"); 179 } 180 } 181 182 public Client() 183 { 184 var _client = new System.Net.Sockets.TcpClient("localhost", 12301); 185 186 Stream = _client.GetStream(); 187 188 this.Value = 0; 189 190 read_value(); 191 } 192 193 ~Client() 194 { 195 Stream.Close(); 196 } 197 198 public event PropertyChangedEventHandler PropertyChanged; 199 200 private void OnPropertyChanged(string name) 201 { 202 if (PropertyChanged != null) 203 { 204 PropertyChanged(this, new PropertyChangedEventArgs(name)); 205 } 206 } 207 208 async void read_value() 209 { 210 var enc = System.Text.Encoding.UTF8; 211 var send_bytes = enc.GetBytes("read"); // 現状送る文字はなんでもよい 212 byte[] result_byte = new byte[256]; 213 214 Stream.Write(send_bytes, 0, send_bytes.Length); 215 216 await Stream.ReadAsync(result_byte, 0, result_byte.Length); 217 218 Value = int.Parse(enc.GetString(result_byte)); 219 220 read_value(); 221 } 222 } 223}

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

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

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

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

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

dodox86

2020/11/21 18:49

> error CS0111: 型 'MainWindow' は、'.ctor' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。 > 何かこのエラーを解消しつつ、1台のPCでソケット通信を実施する方法はないでしょうか? こちらでVisual Studio2017、.NET Framework 4.7.2で軽く試したところではコンパイルエラーは発生しませんね。どのような環境(Visual Studioのバージョン、.NETのバージョン)、ソースファイル構成で試していますか。 「このエラーを解消しつつ」というのが質問の要件にあるので回答しづらいのですが、1台のPCでソケット間通信は別に普通にできます。自PCのIPアドレス、あるいはlocalhost(127.0.0.1)でサーバーとクライアントプログラムを実行するだけです。 「ソケット通信もC#もVisualStudioも素人」なのであれば、もっと簡単なサンプルコードで試した方が良いです。
退会済みユーザー

退会済みユーザー

2020/11/22 01:02

> error CS0111: 型 'MainWindow' は、'.ctor' と呼ばれるメンバーを同じパラメーターの型で既に定義しています。 別ソースでもMainWindowのコンストラクタを定義してないですか?
guest

回答1

0

ベストアンサー

もしソケット通信ができるなら新規でロジックを作成することも考えております。

質問者さんが参考にされたサイトの記事は、「ソケット(TCPのクライアント、サーバー)通信」「非同期」「WPF」「データバインディング」などと様々な要素が入ったものなので、C#の初心者を自認されているのであれば正直、あまりお勧めできません。

以下のような記事を参考に、
.NET ネットワークプログラミング ソケットのコード例 - Microsoft Docs

ひとつずつ理解していくことを強くお勧めします。ソケット通信について、一台のPCでクライアント、サーバーのどちらのプログラムも同時に動作するので心配はいらないです。(IISやApacheのようなWEBサーバーを自PC上で立ち上げて、自PCからWEBブラウザーでアクセスできることと同等です)

参考にされたサイトのプログラムのようなものをご自身で作りたいが、順を追って理解したい、と言うのであれば:

  1. ソケット通信を行うプログラム、TCPのクライアント、サーバーそれぞれを作って理解する。
  2. WPFでのデスクトップウィンドウプログラムを作って理解する。

  ※WPFのデータバインディングは、ソケット通信とは直接関係はありません

  1. WPFのウィンドウで同期式のソケット通信をやってみて、非同期ではない場合にどのような挙動になるのか理解する。

 ※非同期式のプログラミングは、同期型の通信でブロックすること、UIがあれば操作が固まったようになることがなくなりますが、恐らく最初はコードを見ても書いても、何が起こっているか理解しづらいです

のような順番でやっていくと良いと思います。

投稿2020/11/22 02:29

dodox86

総合スコア9183

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

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

Masalu_Kudou

2020/11/22 10:30

通信部分はやりたいけれど、何から始めていいのか全く分からない状態だったので、いただいたアドバイスが大変貴重なものでした!少しずつ、学習を進めていきます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問