【発行側】
public class class1
{
public delegate void _MyEvent(object sender, MyEventArgs e);
public event _MyEvent MyEvent;
protected virtual void MyChangeEvent(MyEventArgs e)
{
if ( MyEvent != null )
{
MyEvent( this, e );
}
}
private void Changed()
{
MyEventArgs e = new MyEventArgs( arg1, arg2 );
MyChangeEvent(e);
}
public class MyEventArgs : EventArgs
{
public string Arg1;
public int Arg2;
...
public MyEventArgs ( string _Arg1, int _Arg2 )
{
Arg1 = _Arg1;
Arg2 = _Arg2;
}
}
}
【受取側】
public class class2
{
private void Define()
{
class1 obj = new class1();
obj.MyEvent += new class1._MyEvent(RecieveEvent);
}
private void RecieveEvent( object sender, class1.MyEventArgs e)
{
Console.WriteLine(e.Arg1 + e.Arg2);
}
}
2016年3月14日月曜日
2016年3月8日火曜日
Wpf細かい書式
毎回忘れる細かい書式
・.Resource内での宣言
<.Resource>
<DataTemplate DataType="{x:Type [namespace]:[class]}" />
</.Resource>
・ListBoxへのBinding
要素が1つなら
<ListBox ItemsSource="{Binding [List]}" DisplayMemberPath="[Listの要素]"/>
要素が複数かつ色々変えるなら
<ListBox ItemsSource="{Binding [List]}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding [要素1]}"/>
<TextBlock Text="{Binding [要素2]}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
選択できなくて良いなら
<ItemsControl ItemsSource="{Binding [List]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="LightPink" CornerRadius="20">
<TextBlock Margin="1">
<!--Run Text="要素1 : " FontSize="10"/-->
<Run Text="{Binding [要素1]}" FontSize="10"/>
<LineBreak/>
<Run Text="要素2 : "/>
<Run Text="{Binding [要素2]}"/>
</TextBlock>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
・PropertyChangedの通知
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
・.Resource内での宣言
<.Resource>
<DataTemplate DataType="{x:Type [namespace]:[class]}" />
</.Resource>
・ListBoxへのBinding
要素が1つなら
<ListBox ItemsSource="{Binding [List]}" DisplayMemberPath="[Listの要素]"/>
要素が複数かつ色々変えるなら
<ListBox ItemsSource="{Binding [List]}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding [要素1]}"/>
<TextBlock Text="{Binding [要素2]}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
選択できなくて良いなら
<ItemsControl ItemsSource="{Binding [List]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="LightPink" CornerRadius="20">
<TextBlock Margin="1">
<!--Run Text="要素1 : " FontSize="10"/-->
<Run Text="{Binding [要素1]}" FontSize="10"/>
<LineBreak/>
<Run Text="要素2 : "/>
<Run Text="{Binding [要素2]}"/>
</TextBlock>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
・PropertyChangedの通知
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
PasswordBoxでデータバインド
【参考】http://garafu.blogspot.jp/2014/09/wcf-passwordbox.html
セキュリティの問題から基本的には非推奨
-----------------------
利用方法
<PasswordBox [namespace]:PasswordBoxHelper.Password = {Binding Target}/>
------------------------
【PasswordBoxHelper.cs】
セキュリティの問題から基本的には非推奨
-----------------------
利用方法
<PasswordBox [namespace]:PasswordBoxHelper.Password = {Binding Target}/>
------------------------
【PasswordBoxHelper.cs】
namespace WpfPasswordBox{ using System.Windows; using System.Windows.Controls; public class PasswordBoxHelper : DependencyObject { public static readonly DependencyProperty IsAttachedProperty = DependencyProperty.RegisterAttached( "IsAttached", typeof(bool), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(false, PasswordBoxHelper.IsAttachedProperty_Changed)); public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached( "Password", typeof(string), typeof(PasswordBoxHelper), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PasswordBoxHelper.PasswordProperty_Changed)); public static bool GetIsAttached(DependencyObject dp) { return (bool)dp.GetValue(PasswordBoxHelper.IsAttachedProperty); } public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordBoxHelper.PasswordProperty); } public static void SetIsAttached(DependencyObject dp, bool value) { dp.SetValue(PasswordBoxHelper.IsAttachedProperty, value); } public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordBoxHelper.PasswordProperty, value); } private static void IsAttachedProperty_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var passwordBox = sender as PasswordBox; if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordBoxHelper.PasswordBox_PasswordChanged; } if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordBoxHelper.PasswordBox_PasswordChanged; } } private static void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { var passwordBox = sender as PasswordBox; PasswordBoxHelper.SetPassword(passwordBox, passwordBox.Password); } private static void PasswordProperty_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var passwordBox = sender as PasswordBox; var newPassword = (string)e.NewValue; if (!GetIsAttached(passwordBox)) { SetIsAttached(passwordBox, true); } if ((string.IsNullOrEmpty(passwordBox.Password) && string.IsNullOrEmpty(newPassword)) || passwordBox.Password == newPassword) { return; } passwordBox.PasswordChanged -= PasswordBoxHelper.PasswordBox_PasswordChanged; passwordBox.Password = newPassword; passwordBox.PasswordChanged += PasswordBoxHelper.PasswordBox_PasswordChanged; } }}2016年2月29日月曜日
ViewModelBaseの代替?
【参考】http://zecl.hatenablog.com/entry/20091211/p1
【IImpleNotifyPropertyChanged.cs】
【IImpleNotifyPropertyChanged.cs】
using System; using System.Linq; using System.Linq.Expressions; using System.ComponentModel; namespace ClassLibrary1 { /// <summary> /// IImpleNotifyPropertyChangedインターフェイス /// /// INotifyPropertyChangedの実装をある程度抽象化し、簡易な実装を提供します。 /// </summary> public interface IImpleNotifyPropertyChanged : INotifyPropertyChanged { /// <summary> /// PropertyChangedの再定義 /// (INotifyPropertyChangedのPropertyChangedを隠蔽する) /// </summary> new event PropertyChangedEventHandler PropertyChanged; /// <summary> /// PropertyChangedEventHandlerを取得します。 /// </summary> PropertyChangedEventHandler PropertyChangedHandler { get; } } /// <summary> /// IImpleNotifyPropertyChangedインターフェイスについて拡張メソッド提供 /// </summary> public static class IImpleNotifyPropertyChangedExtentions { /// <summary> /// プロパティの変更を通知します。 /// </summary> /// <param name="self">対象</param> /// <param name="targets">プロパティ変更通知対象の名称群</param> private static void OnPropertyChanged<TObject>(this TObject self, params string[] propertyNames) where TObject : IImpleNotifyPropertyChanged { if (self == null) return; if (self.PropertyChangedHandler == null) return; foreach (var propertyName in propertyNames) self.PropertyChangedHandler(self, new PropertyChangedEventArgs(propertyName)); } /// <summary> /// プロパティの変更を通知します。 /// </summary> /// <typeparam name="TObject"></typeparam> /// <typeparam name="TExpression"></typeparam> /// <param name="self">対象</param> /// <param name="expressions">プロパティ変更通知対象の名称を取得するExpression群</param> public static void OnPropertyChanged<TObject, TExpression>(this TObject self, params Expression<Func<TObject, TExpression>>[] expressions) where TObject : IImpleNotifyPropertyChanged { var propertyNames = from e in expressions select ((MemberExpression)e.Body).Member.Name; self.OnPropertyChanged(propertyNames.ToArray()); } } /// <summary> /// INotifyPropertyChangedインターフェイスについて拡張メソッドを提供 /// </summary> public static class INotifyPropertyChangedExtentions { /// <summary> /// プロパティ変更イベントの関連付け補助 /// </summary> /// <typeparam name="TObject"></typeparam> /// <typeparam name="TExpression"></typeparam> /// <param name="self"></param> /// <param name="expressions"></param> /// <param name="handler"></param> public static void AddPropertyChanged<TObject, TExpression>(this TObject self, Expression<Func<TObject, TExpression>> expressions, Action<TObject> handler) where TObject : INotifyPropertyChanged { if (self == null) return; var propName = ((MemberExpression)expressions.Body).Member.Name; self.PropertyChanged += (sender, e) => { if (e.PropertyName == propName) handler(self); }; } } }
RelayCommand.cs
【参考】http://d.hatena.ne.jp/kaorun/20141202/1417532472
ICommandの簡単実装
--------------------------
ViewModel内で宣言
・宣言
public ICommand Event_name { get; set; }
・コンストラクタで初期化
Event_name = new RelayCommand( Process_name );
・実処理は別に作成(簡単な処理ならlambdaで)
public void Process_name(){
処理内容;
(例:インクリメント、メッセージボックス表示)
}
--------------------------
Common内で定義
【RelayCommand.cs】
using System;
using System.Windows.Input;
namespace Project.Common
{
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action execute) : this(execute, null)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
ICommandの簡単実装
--------------------------
ViewModel内で宣言
・宣言
public ICommand Event_name { get; set; }
・コンストラクタで初期化
Event_name = new RelayCommand( Process_name );
・実処理は別に作成(簡単な処理ならlambdaで)
public void Process_name(){
処理内容;
(例:インクリメント、メッセージボックス表示)
}
--------------------------
Common内で定義
【RelayCommand.cs】
using System;
using System.Windows.Input;
namespace Project.Common
{
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action execute) : this(execute, null)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
2016年1月26日火曜日
非同期ソケット通信サーバー側
試行錯誤中のゴミが大量混入ver
class SocketServer
{
//ホスト名からIPアドレスを取得する時は、次のようにする
//string host = "localhost";
//System.Net.IPAddress ipAdd =
// System.Net.Dns.GetHostEntry(host).AddressList[0];
//.NET Framework 1.1以前では、以下のようにする
//System.Net.IPAddress ipAdd =
// System.Net.Dns.Resolve(host).AddressList[0];
private System.Net.Sockets.TcpClient objSckClient;
System.Net.Sockets.NetworkStream SendNS;
private System.Net.Sockets.TcpListener objSckServer;
private System.Threading.Thread ListeningCallbackThread;
private volatile bool SLTAlive;
private volatile bool SendAlive;
public SocketServer()
{
objSckClient = new System.Net.Sockets.TcpClient();
SLTAlive = false;
SendAlive = false;
//---------------------
InvokeMethod = new InvokeMethodDelegate(BeginInvokeTypeMethod);
Caller = new CommunicationCallbackDelegate(CommunicationCallback);
}
public void Recieve_Close()
{
if (SLTAlive)
{
SLTAlive = false;
objSckServer.Stop();
ListeningCallbackThread = null;
}
}
public void Recieve_Stop()
{
if (objSckServer != null)
{
objSckServer.Stop();
}
SLTAlive = false;
Console.WriteLine("サーバー正常終了");
}
public void Recieve_CreateThread()
{
SLTAlive = true;
ListeningCallbackThread = new System.Threading.Thread(ListeningCallback);
ListeningCallbackThread.Start();
}
private void ListeningCallback()
{
objSckServer = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 12323);
objSckServer.Start();
Console.WriteLine("サーバー開始");
try
{
int cnt = 0;
while (SLTAlive)
{
cnt++;
Console.WriteLine("1, " + cnt);
if (objSckServer.Pending())
{
Console.WriteLine("2, " + cnt);
System.Net.Sockets.TcpClient ClientSocket = objSckServer.AcceptTcpClient();
Console.WriteLine("connected : " + ((System.Net.IPEndPoint)ClientSocket.Client.RemoteEndPoint).Address + ", " + ((System.Net.IPEndPoint)ClientSocket.Client.RemoteEndPoint).Port);
System.Net.Sockets.NetworkStream stream = ClientSocket.GetStream();
byte[] RecieveData = new Byte[2000];
int DataLength = stream.Read(RecieveData, 0, RecieveData.Length);
string str = System.Text.Encoding.Unicode.GetString(RecieveData, 0, DataLength);
Console.WriteLine("受け取り手:" + str);
byte[] SendBuffer = System.Text.Encoding.Unicode.GetBytes("サーバーメッセージ");
stream.Write(SendBuffer, 0, SendBuffer.Length);
stream.Flush();
ClientSocket.Close();
}
System.Threading.Thread.Sleep(100);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public void Send_Connect()
{
objSckClient.Connect("127.0.0.1", 12323);
Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。", ((System.Net.IPEndPoint)objSckClient.Client.RemoteEndPoint).Address, ((System.Net.IPEndPoint)objSckClient.Client.RemoteEndPoint).Port, ((System.Net.IPEndPoint)objSckClient.Client.LocalEndPoint).Address, ((System.Net.IPEndPoint)objSckClient.Client.LocalEndPoint).Port);
SendNS = objSckClient.GetStream();
SendNS.ReadTimeout = 10000; //10sec
SendNS.WriteTimeout = 10000; //*1ms
SendAlive = true;
}
public void Send_Execute()
{
if (SendAlive)
{
String SendMessage = "メッセージ送信";
byte[] sendBytes = System.Text.Encoding.Unicode.GetBytes(SendMessage + "\n");
SendNS.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine("送り手:メッセージ送信済");
}
}
public void Send_Close()
{
if (SendAlive)
{
SendNS.Close();
objSckClient.Close();
Console.WriteLine("クライアントとの接続終了");
}
}
//--------------------------------------------------------------------------------------------------------------
//メンバ変数
// 送受信電文処理スレッド呼び出し用オブジェクト
private CommunicationCallbackDelegate Caller;
// 送受信電文処理メソッド用デリゲート
delegate ProcessingResultOfCommunication CommunicationCallbackDelegate(System.Net.Sockets.TcpListener listener);
// 待機中のスレッドを管理するオブジェクト
public static System.Threading.ManualResetEvent AllDone = new System.Threading.ManualResetEvent(false);
//----------------------------------------------------------------------------------------------------------------
public class ProcessingResultOfCommunication
{
public string ReceivedData; // 受信データ
public string Reply; // 返信(送信データ)
}
//----------------------------------------------------------------------------------------------------------------
public void Recieve_Start2()
{
if (!SLTAlive) // まだ接続待ちスレッドを生成していない場合
{
// リスナー(接続要求受け入れ待機)を生成
objSckServer = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 12323);
// *** server = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 9000);
// 接続要求受け入れ開始
objSckServer.Start();
// 接続待ち用スレッドを作成
ListeningCallbackThread = new System.Threading.Thread(ListeningCallback2);
// 接続待ち用スレッドを開始
ListeningCallbackThread.Start();
// スレッド終了指示フラグを未終了に設定
SLTAlive = true;
}
}
// ************************************
// 接続待ちスレッド用メソッド
// --- クライアントからの受信受け付けを行なうメソッドです。なお、受信受
// け付けを常に行なうため、無限ループで受け付け処理を行っています。
// 無限ループは、処理を占有して、本サーバープログラム自体の動作に影
// 響しますので、本メソッドは、スレッドとして起動します。
// ************************************
private void ListeningCallback2()
{
// label1.Text = "サーバー開始";
Console.WriteLine("サーバー開始");
try
{
// 受信の受付を行なうための無限ループ
while (SLTAlive) // スレッド終了指示フラグでの終了指示がある場合はループ終了
{
// 受信接続キュー内で、接続待ちがあるか判断
if (objSckServer.Pending() == true)
{
// AllDoneを非シグナル状態にする
// すなわち、スレッドの実行指示の状態をリセットして戻す。
AllDone.Reset();
// スレッドを起動し、送受信電文処理スレッド用メソッドを実行します。
InvokeMethod();
// AllDoneがシグナル状態になるまでスレッドをブロック。
// すなわち、送受信電文処理用スレッドから、実行開始の指示が出るまで待機する。
AllDone.WaitOne();
}
// 短時間だけ待機
System.Threading.Thread.Sleep(100);
}
}
catch (Exception ex)
{
Console.WriteLine("サーバー終了\n" + ex);
}
}
//----------------------------------------------------------------------------------------------------------------
//========================
// 電文処理スレッド起動メソッド用デリゲート
//========================
delegate void InvokeMethodDelegate();
private InvokeMethodDelegate InvokeMethod;
//----------------------------------------------------------------------------------------------------------------
// ************************************
// 送受信電文処理スレッド用メソッド
// --- 受信された電文に対して、具体的な処理を行なうメソッドです。このサ
// ンプルでは、受信電文をテキストボックスに表示し、また、クライアン
// トへ返信を返す処理としています。
// なお、本メソッド(電文処理部)は、複数のクライアントからの接続に対
// 応しています。すなわち、受信があるたびにスレッドが起動し、本メソ
// ッドが実行されます。
// 第1引数: クライアントからの受信接続要求を処理するリスナー
// 戻り値: 処理結果
// ************************************
public ProcessingResultOfCommunication CommunicationCallback(System.Net.Sockets.TcpListener listener)
{
// AllDoneをシグナル状態にする。
// すなわち、接続待ちスレッドのロックを解除して、接続待ちスレッドの実行再開の許可をする。
AllDone.Set();
// 処理結果格納用クラスの生成
ProcessingResultOfCommunication ResultData = new ProcessingResultOfCommunication();
if (SLTAlive) // 接続待ちスレッドが作成されていて使える場合
{
try
{
// クライアントからの接続を受け付ける
System.Net.Sockets.TcpClient ClientSocket = listener.AcceptTcpClient(); // TCPクライアント
// 通信ストリームの取得
System.Net.Sockets.NetworkStream stream = ClientSocket.GetStream();
//============
// クライアントからの電文の受信
byte[] ReceiveData = new byte[2000];
int DataLength = stream.Read(ReceiveData, 0, ReceiveData.Length); // 電文の列長
string str = System.Text.Encoding.Unicode.GetString(ReceiveData, 0, DataLength);
//============
// 処理結果格納用クラスに本メソッドの処理結果を格納
// 受信データーを処理結果格納用クラスに設定
ResultData.ReceivedData = str;
// 返信データーの作成
ResultData.Reply = "通信データー<< " + str + ">>を受け取りました。";
//============
// サーバーで処理時間のかかる処理が行なわれる場合を、仮に実験したい
// 場合は、下記の時間待機のメソッドを実行させて下さい。
// *** System.Threading.Thread.Sleep(30000);
//============
// 返信電文をクライアントへ送信
byte[] SendBuffer = System.Text.Encoding.Unicode.GetBytes(ResultData.Reply);
stream.Write(SendBuffer, 0, SendBuffer.Length);
stream.Flush(); // フラッシュ(強制書き出し)
// 通信ストリームをクローズ
stream.Close();
// TCPクライアントをクローズ
ClientSocket.Close();
}
catch (Exception ex)
{
}
}
return ResultData;
}
//------------------------------------------------------------------------------------------
//========================
// ノンブロッキング通信指定時に使われるメソッド
//========================
//========================
// ノンブロッキング通信指定時の電文処理スレッド起動用メソッド
private void BeginInvokeTypeMethod()
{
// ワーカースレッドでの処理終了時に起動するコールバックメソッドを指定
AsyncCallback asc = new AsyncCallback(ReturnCallback);
// スレッドを起動し、送受信電文処理スレッド用メソッドを実行します。
IAsyncResult AsyRes = Caller.BeginInvoke(objSckServer, asc, null);
//IAsyncResult AsyRes = Caller.BeginInvoke(ServerSocket, asc, new object[] { ServerSocket });
}
//========================
// スレッド完了時起動のコールバックメソッド
// BeginInvokeでの呼び出し(非同期呼び出し)で起動されるスレッドにおいて、
// その処理が完了した時に、呼び出し元に呼び出されるメソッドです。
// よって、ワーカースレッド(BeginInvokeで呼び出されるスレッド)での処理
// 結果に関する処理等をここに定義すると便利です。
// 第1引数: 非同期デリゲートでの非同期操作の結果(をカプセル化した物)
public void ReturnCallback(IAsyncResult AsyRes)
{
// 結果を取り出すための非同期結果のキャスト。
System.Runtime.Remoting.Messaging.AsyncResult aResult = (System.Runtime.Remoting.Messaging.AsyncResult)AsyRes;
// 非同期の呼び出しが行われたデリゲート オブジェクトを取得。
CommunicationCallbackDelegate dele = (CommunicationCallbackDelegate)aResult.AsyncDelegate;
// デリゲートの完了処理を実行。及びワーカースレッドでの処理結果の受け取り。
ProcessingResultOfCommunication ResultData = dele.EndInvoke(AsyRes);
// 受信データを表示
//textBox1.Text += ResultData.ReceivedData + "\r\n";
Console.WriteLine(ResultData.ReceivedData);
}
}
【参考】http://note.chiebukuro.yahoo.co.jp/detail/n26284
ソケット通信クライアント側
class SocketClient2
{
public SocketClient2() { }
public void mai(String ipOrHost, int port, String sendMsg)
{
if (sendMsg == null || sendMsg.Length == 0)
{
return;
}
//TcpClientを作成し、サーバーと接続する
System.Net.Sockets.TcpClient tcp =
new System.Net.Sockets.TcpClient(ipOrHost, port);
Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。",
((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Address,
((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Port,
((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Address,
((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Port);
//NetworkStreamを取得する
System.Net.Sockets.NetworkStream ns = tcp.GetStream();
//読み取り、書き込みのタイムアウトを10秒にする
//デフォルトはInfiniteで、タイムアウトしない
//(.NET Framework 2.0以上が必要)
ns.ReadTimeout = 10000;
ns.WriteTimeout = 10000;
//サーバーにデータを送信する
//文字列をByte型配列に変換
//System.Text.Encoding enc = System.Text.Encoding.UTF8;
System.Text.Encoding enc = System.Text.Encoding.Unicode;
byte[] sendBytes = enc.GetBytes(sendMsg + '\n');
//データを送信する
ns.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine(sendMsg);
//サーバーから送られたデータを受信する
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] resBytes = new byte[256];
int resSize = 0;
do
{
//データの一部を受信する
resSize = ns.Read(resBytes, 0, resBytes.Length);
//Readが0を返した時はサーバーが切断したと判断
if (resSize == 0)
{
Console.WriteLine("サーバーが切断しました。");
break;
}
//受信したデータを蓄積する
ms.Write(resBytes, 0, resSize);
//まだ読み取れるデータがあるか、データの最後が\nでない時は、
// 受信を続ける
} while (ns.DataAvailable || resBytes[resSize - 1] != '\n');
//受信したデータを文字列に変換
string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length);
ms.Close();
//末尾の\nを削除
resMsg = resMsg.TrimEnd('\n');
Console.WriteLine(resMsg);
//閉じる
ns.Close();
tcp.Close();
}
}
【参考】http://dobon.net/vb/dotnet/internet/tcpclientserver.html
登録:
投稿 (Atom)