0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windowsフォームのグローバル変数がうまく行かなかった話

Last updated at Posted at 2024-08-07

グローバル変数がうまく行かなかった

C#初めて3日経ちましたがアプリ開発でグローバル変数がうまく使えず半日つぶしたので、Aiに頼ってみました。

サーバー側

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
   public partial class Form1 : Form
   {
       private TcpListener listener;
       private CancellationTokenSource cts;
       private TcpClient connectedClient;

       public Form1()
       {
           InitializeComponent();
       }

       private void Form1_Load(object sender, EventArgs e)
       {
           // サーバーをTaskで非同期に起動
           cts = new CancellationTokenSource();
           Task.Run(() => StartTcpClient(cts.Token));
       }

       public async void StartTcpClient(CancellationToken token)
       {
           listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 11000);
           listener.Start();
           AppendText("Server started. Waiting for a connection...");

           try
           {
               while (!token.IsCancellationRequested)
               {
                   connectedClient = await listener.AcceptTcpClientAsync();
                   AppendText("Client connected!");

                   // クライアントのメッセージを受信
                   Task.Run(() => RecvTcpClient(connectedClient, token));
               }
           }
           catch (Exception ex)
           {
               AppendText($"Exception: {ex.Message}");
           }
       }

       public void StopTcpClient()
       {
           cts.Cancel();
           listener.Stop();
           AppendText("Server stopped.");
       }

       public async void RecvTcpClient(TcpClient client, CancellationToken token)
       {
           NetworkStream stream = client.GetStream();
           byte[] buffer = new byte[1024];
           int bytesRead;

           try
           {
               while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) != 0)
               {
                   string receivedData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                   AppendText($"Received: {receivedData}");

                   // 受信したメッセージを返送
                  // byte[] responseData = Encoding.ASCII.GetBytes("Message received");
                   //await stream.WriteAsync(responseData, 0, responseData.Length, token);
                   //AppendText("Sent: Message received");
               }
           }
           catch (Exception ex)
           {
               AppendText($"Exception: {ex.Message}");
           }
           finally
           {
               client.Close();
               AppendText("Client disconnected.");
           }
       }

       private void button2_Click(object sender, EventArgs e)
       {
           string message = textBox1.Text;
           SendMessageToClient(message);
       }

       public async void SendMessageToClient(string message)
       {
           if (connectedClient != null && connectedClient.Connected)
           {
               NetworkStream stream = connectedClient.GetStream();
               byte[] msg = Encoding.ASCII.GetBytes(message);
               await stream.WriteAsync(msg, 0, msg.Length);
               AppendText($"Sent to client: {message}");
           }
           else
           {
               AppendText("No client connected.");
           }
       }

       private void AppendText(string text)
       {
           if (InvokeRequired)
           {
               Invoke((Action)(() => label1.Text = text + Environment.NewLine));
           }
           else
           {
               label1.Text=text + Environment.NewLine;
           }
       }

       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
       {
           StopTcpClient();
       }
   }
}

クライアント側

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
   public partial class Form1 : Form
   {
       private TcpClient client;
       private NetworkStream stream;

       public Form1()
       {
           InitializeComponent();
       }

       // クライアントとしてサーバーに接続する
       public async void Connect()
       {
           try
           {
               client = new TcpClient("127.0.0.1", 11000);
               stream = client.GetStream();
               AppendText("Connected to server.");

               // サーバーからのメッセージを非同期で受信
               await Task.Run(() => Recv());
           }
           catch (Exception ex)
           {
               AppendText($"Exception: {ex.Message}");
           }
       }

       // tcpクライアントにメッセージを送信するメソッドを非同期で実行する
       private void button2_Click(object sender, EventArgs e)
       {
           Send();
       }

       // tcpクライアントにメッセージを送信する
       public async void Send()
       {
           if (client != null && client.Connected)
           {
               string message = textBox1.Text;
               byte[] data = Encoding.ASCII.GetBytes(message);

               try
               {
                   await stream.WriteAsync(data, 0, data.Length);
                   AppendText($"Sent: {message}");
               }
               catch (Exception ex)
               {
                   AppendText($"Exception: {ex.Message}");
               }
           }
           else
           {
               AppendText("Client is not connected.");
           }
       }

       // tcpクライアントからメッセージを受信する
       public async void Recv()
       {
           byte[] buffer = new byte[1024];
           int bytesRead;

           try
           {
               while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
               {
                   string receivedData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                   AppendText($"Received: {receivedData}");
               }
           }
           catch (Exception ex)
           {
               AppendText($"Exception: {ex.Message}");
           }
       }

       private void AppendText(string text)
       {
           if (InvokeRequired)
           {
               Invoke((Action)(() => label1.Text = text + Environment.NewLine));
           }
           else
           {
               label1.Text = text + Environment.NewLine;
           }
       }

       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
       {
           if (client != null)
           {
               client.Close();
           }
       }


       private void button1_Click_1(object sender, EventArgs e)
       {
           Connect();
       }
   }
}

説明

サーバー側

Form1_Load:

フォームがロードされたときにサーバーを非同期に起動します。
StartTcpClient:

TcpListenerを初期化し、クライアントの接続を待機します。
接続されたクライアントごとにRecvTcpClientを非同期に実行します。
StopTcpClient:

サーバーを停止し、CancellationTokenSourceをキャンセルします。
RecvTcpClient:

クライアントからのメッセージを受信し、受信したメッセージを返送します。
受信したメッセージはテキストボックスに表示されます。
button2_Click:

ボタンがクリックされたときに、テキストボックスの内容をクライアントに送信します。
SendMessageToClient:

クライアントにメッセージを送信します。クライアントが接続されていない場合は、その旨を表示します。
AppendText:

テキストボックスにテキストを追加します。スレッドセーフな方法でUIを更新するためにInvokeを使用しています。
Form1_FormClosing:

フォームが閉じられるときにサーバーを停止します。

クライアント側

Connectメソッド:

サーバーに接続します。接続が成功すると、サーバーからのメッセージを非同期で受信するタスクを開始します。
Sendメソッド:

テキストボックスに入力されたメッセージをサーバーに送信します。非同期で実行され、メッセージが送信されたことを確認します。
Recvメソッド:

サーバーからのメッセージを非同期で受信し、受信したメッセージをテキストボックスに表示します。
AppendTextメソッド:

スレッドセーフにテキストボックスにテキストを追加します。
Form1_FormClosingメソッド:

フォームが閉じられるときにクライアント接続をクローズします。
button1_Clickメソッド:

サーバーに接続するためのボタンのクリックイベントハンドラです。

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?