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

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

## サーバー側
 ```cs
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();
        }
    }
}

 ```
## クライアント側
 ```cs
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メソッド:

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