TcpClient - TcpListener Testtool C#

Markus Freitag 3,786 Reputation points
2022-04-22T08:18:14.63+00:00

Hello,
I am looking for a good example server client.
With reconnection in case of error, both sides.
When I send a request, I want a response in a certain time.

How can I achieve this?

When I close the application everything should close cleanly. However, I am in an infinite loop. What is the best way to do this?


Client

namespace Client
{
    public partial class Client : Form
    {
        public Client()
        {
            InitializeComponent();
        }

        TcpClient MyTcpClient = new TcpClient();

        //Declare and Initialize the IP Adress
        IPAddress ipAd = IPAddress.Parse("127.0.0.1");

        //Declare and Initilize the Port Number;
        int PortNumber = 8888;



        private void Client_Load(object sender, EventArgs e)
        {
            Console.WriteLine("Connecting.....");
            try
            {
                MyTcpClient.Connect(ipAd, PortNumber);
                txtStatus.Text += Environment.NewLine + "Connected";
                txtStatus.Text += Environment.NewLine + "Enter the string to be transmitted";
            }
            catch { }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            String str = txtEnviar.Text + "$";
            Stream stm = MyTcpClient.GetStream();

            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] ba = asen.GetBytes(str);

            txtStatus.Text += Environment.NewLine + "Transmitting...";
            //Console.WriteLine("Transmitting.....");

            stm.Write(ba, 0, ba.Length);

            byte[] bb = new byte[100];
            int k = stm.Read(bb, 0, 100);   // ** Timeout ? reconnect....

            string Response = Encoding.ASCII.GetString(bb);

            txtStatus.Text += Environment.NewLine + "Response from server: " + Response;

        }       
    }
}

Server

namespace Server
{
    public partial class Server : Form
    {
        public Server()
        {
            InitializeComponent();
        }

        //Declare and Initialize the IP Address
        static IPAddress ipAd = IPAddress.Parse("127.0.0.1");

        //Declare and Initilize the Port Number;
        static int PortNumber = 8888;

        /* Initializes the Listener */
        TcpListener ServerListener = new TcpListener(ipAd, PortNumber);
        TcpClient clientSocket = default(TcpClient);



        private void Server_Load(object sender, EventArgs e)
        {
            Thread ThreadingServer = new Thread(StartServer);
            ThreadingServer.Start();
        }

        private void THREAD_MOD(string teste)
        {
            txtStatus.Text += Environment.NewLine + teste;
        }

        private void StartServer()
        {
            Action<string> DelegateTeste_ModifyText = THREAD_MOD;
            ServerListener.Start();
            Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
            clientSocket = ServerListener.AcceptTcpClient();
            Invoke(DelegateTeste_ModifyText, "Server ready!");

            while (true)     // Operator press close the application or cancel  -- However, I am in an infinite loop. What is the best way to do this?
            {
                try
                {    
                    NetworkStream networkStream = clientSocket.GetStream();
                    byte[] bytesFrom = new byte[20];
                    networkStream.Read(bytesFrom, 0, 20);
                    string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                    Invoke(DelegateTeste_ModifyText, $"From Client: {dataFromClient}  !");


                    string serverResponse = "Received!";
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                }
                catch
                {
                    ServerListener.Stop();
                    ServerListener.Start();
                    Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
                    clientSocket = ServerListener.AcceptTcpClient();
                    Invoke(DelegateTeste_ModifyText, "Server ready!");
                }

            }
        }

    }
}
Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,839 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,309 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jack J Jun 24,296 Reputation points Microsoft Vendor
    2022-04-25T07:01:19.19+00:00

    @Markus Freitag , based on my test, I reproduced your problem about the app will still be in an infinite loop when you close the server app.

    I made some changes on your code about StartServer method, now it could work it well when you connected to client and click the close button.

    Server code:

    public partial class Form1 : Form  
        {  
            public Form1()  
            {  
                InitializeComponent();  
            }  
            static IPAddress ipAd = IPAddress.Parse("127.0.0.1");  
      
            //Declare and Initilize the Port Number;  
            static int PortNumber = 8888;  
      
            /* Initializes the Listener */  
            TcpListener ServerListener = new TcpListener(ipAd, PortNumber);  
            TcpClient clientSocket = default(TcpClient);  
      
            Thread ThreadingServer;  
            public BinaryReader br;  
            public BinaryWriter bw;  
            private void Form1_Load(object sender, EventArgs e)  
            {  
                ThreadingServer = new Thread(StartServer);  
      
                ThreadingServer.Start();  
            }  
      
            private void THREAD_MOD(string teste)  
            {  
                txtStatus.Text += Environment.NewLine + teste;  
            }  
      
            private void StartServer()  
            {  
                try  
                {  
                    Action<string> DelegateTeste_ModifyText = THREAD_MOD;  
                    ServerListener.Start();  
                    Invoke(DelegateTeste_ModifyText, "Server waiting connections!");  
                    clientSocket = ServerListener.AcceptTcpClient();  
                    Invoke(DelegateTeste_ModifyText, "Server ready!");  
                    while (true)     // Operator press close the application or cancel  -- However, I am in an infinite loop. What is the best way to do this?  
                    {  
                        try  
                        {  
                            NetworkStream clientStream = clientSocket.GetStream();  
                            br = new BinaryReader(clientStream);  
                            string receive = null;  
                            receive = br.ReadString();  
                            txtStatus.Invoke((MethodInvoker)delegate { txtStatus.Text += receive; });  
      
                        }  
                        catch  
                        {  
                            if (clientSocket.Connected == false)  
                            {  
                                MessageBox.Show("the connection is closed");  
                            }  
                            else  
                            {  
                                MessageBox.Show(ex.ToString());  
                            }  
                            clientSocket.Close();  
                        }  
                        
                        
                    }  
      
                }    
                catch (Exception ex)  
                {  
      
                    if (clientSocket.Connected == false)  
                    {  
                        MessageBox.Show("the connection is closed");  
                    }  
                    else  
                    {  
                        MessageBox.Show(ex.ToString());  
                    }  
                    clientSocket.Close();  
      
      
                }  
                finally  
                {  
                    ServerListener.Stop();  
                }  
            }  
      
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)  
            {  
                clientSocket.Close();  
      
            }  
        }  
    

    Client code:

    public partial class Form1 : Form  
        {  
            public Form1()  
            {  
                InitializeComponent();  
            }  
      
            private TcpClient client;  
            public BinaryReader br;  
            public BinaryWriter bw;  
            private void Form1_Load(object sender, EventArgs e)  
            {  
                Thread myThread = new Thread(ClientA);  
                myThread.Start();  
            }  
      
            private void ClientA()  
            {  
                client = new TcpClient("127.0.0.1", 8888);  
      
                Console.WriteLine("Connected to server");  
                txtStatus.Invoke((MethodInvoker)delegate { txtStatus.Text = "Connected to server"; });  
                while (true)  
                {  
                    try  
                    {  
                        NetworkStream clientStream = client.GetStream();  
                        br = new BinaryReader(clientStream);  
                        string receive = null;  
                        receive = br.ReadString();  
                        txtEnviar.Invoke((MethodInvoker)delegate { txtEnviar.Text = receive; });  
                          
                    }  
                    catch  
                    {  
                        MessageBox.Show("the server connection is closed!");  
                        break;  
                    }  
                }  
            }  
      
            private void button1_Click(object sender, EventArgs e)  
            {  
                NetworkStream clientStream = client.GetStream();  
                bw = new BinaryWriter(clientStream);  
                bw.Write(txtEnviar.Text);  
           
      
      
      
            }  
      
              
                 
              
        }  
    

    Best regards,
    Jack


    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.