question

MarkusFreitag-0088 avatar image
0 Votes"
MarkusFreitag-0088 asked MarkusFreitag-0088 edited

TcpClient - TcpListener Testtool C#

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!");
                 }
    
             }
         }
          
     }
 }


dotnet-csharpwindows-forms
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@MarkusFreitag-0088, is any update? I have updated my answer and do you have time to checj it?

0 Votes 0 ·

1 Answer

JackJJun-MSFT avatar image
1 Vote"
JackJJun-MSFT answered MarkusFreitag-0088 edited

@MarkusFreitag-0088 , 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.gif (237.4 KiB)
· 17
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

First thanks!

I have to read until the end sign $ or \n\r comes. Is not included now.

I close the server window. Is closed, visible false, but application is running.
Yes, that’s difficult, my problem. How can I solve it?

    while (true)     // Operator press close the application or cancel 
    
 // here is no break....

That's where I'm looking for a solution. It's difficult, I know.

Maybe if I get it explained well it's not difficult after all, if I know what the right way is.
When I close the client, an exception on server site appears.


How can I set up an automatic reconnection

  • for the client

  • for the server

provide? How does the programming look like?
195970--server-test-1.png


0 Votes 0 ·
-server-test-1.png (146.7 KiB)
JackJJun-MSFT avatar image JackJJun-MSFT MarkusFreitag-0088 ·

@ MarkusFreitag-0088, I want to know when you close the server app. In my situation, I open the server app then open client app, then I close the server app, it could close server app successfully. If you open the server app and without opening client then close the server app, I think there is meaningless. Because the Server is just used to wait for the connection for the client.

1 Vote 1 ·

Start server
Start Client
Send message to server
Close the server with the X from the window
Server does not close correctly. It hangs in the infinite loop. The main problem.


How would you solve the end criterion?
$ or \n\r or
When XML
StartElement
EndElement.
It may be that the message is sent in two, three or four packets.
Like this

 <Message>
   <MyObjectProperty>
     <ObjectName xPos= "45.53" yPos ="100">Price</ObjectName>
     <ObjectName>Unit</ObjectName>
     <ObjectName zPos ="200">Depth</ObjectName>
   </MyObjectProperty>
 </Message>


I think we need cancellation of a thread. I don't know how to apply this.


196528-serverstill-open.png


0 Votes 0 ·
serverstill-open.png (174.0 KiB)

Do you have any tip for me.


That would be very nice of you.
Thanks in advance for your help.

   while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                  {

How do I get out of the loop? When I press cancel or close the windows form dialog?

0 Votes 0 ·
Show more comments