c#多个tcpclient使其中一个客户端断开连接几秒钟

本文关键字:断开 客户端 连接 几秒 一个 tcpclient 多个 | 更新日期: 2023-09-27 18:24:57

我正在尝试制造一个机器人。为此,我需要大约6个arduino以太网,它们连接到连接到计算机的Cisco集线器。我的c代码是基于线程的,所以它可以处理多个客户端。工作完成后,服务器断开连接,然后客户端重新连接。客户端连接-断开连接以100ms重新连接。在这种情况下,arduino以太网连续发送和接收数据。所有的连接都在端口23上进行。每个客户都有不同的ipad地址。

问题:

最初,当我启动服务器时,所有服务器都会连接,但几秒钟后,其中一个服务器会冻结3-4秒,之后它会连接,当它重新连接时,其他一些服务器将处于冻结状态。

如果我将arduino代码中的延迟从100ms增加到400ms,所有这些代码都可以正常连接。但对于我的机器人进程,我需要它以100毫秒的速度工作。

我无法弄清楚aduino以太网这种奇怪行为的原因。已经完成了所有的基本测试,有些地方感觉到了arduino的问题。

以下是我的c#和我的arduino代码(所有6个都有相同的代码,只是发送和接收的数据不同)

C#代码:

        using System.Threading;
        using System.IO;
        using System.Net;
        using System.Net.Sockets;
        namespace client_server_demo
        {
            /// <summary>
            /// Interaction logic for MainWindow.xaml
            /// </summary>
            public partial class MainWindow : Window
            {
                // input data is stored into s
                string receiving_data = "";
                int port_no = 23;
                // the index of %
                int receiving_data_length;
                // sonar sensors data
                int[] sonar_sensor_data = { 0, 0, 0, 0 };
                bool[] limit_switch = { false, false, false, false };
                // data to arduinos
                string sending_data = "";
                byte[] c1;

                //store ipaddress of connected client
                string ipaddress_client = "";
                //error msg of disconnection
                string disconnect_error = "";
                /// <summary>
                /// start of the form
                /// </summary>
                public MainWindow()
                {
                    InitializeComponent();
                    Thread tcpthread = new Thread(new ThreadStart(tcpserverRun));
                    tcpthread.Start();
                }
                /// <summary>
                /// connects to the clients on port 23 
                /// </summary>
                private void tcpserverRun()
                {
                    TcpListener tcplistener = new TcpListener(IPAddress.Any, port_no);
                    updateUi("listening");
                    tcplistener.Start();
                    while (true)
                    {
                        TcpClient client = tcplistener.AcceptTcpClient();
                        updateUi("connected");
                        //for multiple clients use thread
                        Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcphandler));
                        tcpHandlerThread.Start(client);
                    }
                }

                private void tcphandler(object client)
                {
                    try
                    {
                        TcpClient mclient = (TcpClient)client;          // create client
                        Socket so = mclient.Client;                        // create a socket so as to get the ipaddress of the client
                        NetworkStream stream = mclient.GetStream();
                        //read data from the port
                        byte[] message = new byte[100];
                        stream.Read(message, 0, message.Length);
                        receiving_data = Encoding.ASCII.GetString(message);
                        receiving_data_length = receiving_data.IndexOf('%');
                        //remove garbage ahead of %
                        receiving_data = receiving_data.Substring(0, receiving_data_length + 1);
                        //get ipaddress of the client connected
                        ipaddress_client = (IPAddress.Parse(((IPEndPoint)so.RemoteEndPoint).Address.ToString())).ToString();
                        // show the string on ui -> ip addres+ data
                        updateUi(ipaddress_client + " : " + receiving_data);

                       //send data
                        if (receiving_data == "R%")
                        {
                            //send to the arduino
                            sending_data = "Welcome client 1 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                      }

                        if (receiving_data == "S%")
                        {
                            sending_data = "Welcome client 2 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                        }
                        if (receiving_data == "L%")
                        {
                            sending_data = "Welcome client 3 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                        }
         if (receiving_data == "T%")
                        {
                            sending_data = "Welcome client 4 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                        }
         if (receiving_data == "J%")
                        {
                            sending_data = "Welcome client 5 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                        }
         if (receiving_data == "A%")
                        {
                            sending_data = "Welcome client 6 %";
                            ASCIIEncoding asen = new ASCIIEncoding();
                            c1 = asen.GetBytes(sending_data);
                            stream.Write(c1, 0, c1.Length);
                        }
                        //clos al the streams and client so as to avaoid memory leakage
                        stream.Flush();
                        stream.Close();
                        mclient.Close();

                    }
                    catch (Exception e)
                    {
                        updateException(e.StackTrace);
                    }
                }
                /// <summary>
                /// for updating the form as per data received from the clients 
                /// </summary>
                /// <param name="s"></param>
                private void updateUi(string s)
                {
                    Func<int> del = delegate()
                    {
                        textBox1.AppendText(s + System.Environment.NewLine);
                        label1.Content = "connected";
                        label2.Content = "";
                        textBox1.ScrollToEnd();
                        return 0;
                    };
                    Dispatcher.Invoke(del);
                }
                /// <summary>
                /// for showing if any error occurred
                /// </summary>
                /// <param name="s"></param>
                private void updateException(string s)
                {
                    Func<int> del = delegate()
                    {
                        label1.Content = "";
                        label2.Content = "Error : " + s;
                        return 0;
                    };
                    Dispatcher.Invoke(del);
                }

        }

在arduino代码中,在led的帮助下,我了解了它是否接收到数据。计时器会跟踪,如果它没有从服务器获取数据,那么它会保持led亮起。否则它会闪烁。如果未连接到服务器,它将关闭。

    arduino code:
    #include "Wire.h"
    #include "I2Cdev.h" // libraries
    #include <SPI.h>
    #include <Ethernet.h>
    #include <SimpleTimer.h>
    byte mac[] = {
      0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    }
    ;
    char server[] = "192.168.0.50";    //ipaddress of the joystick ethernet
    IPAddress ip(192, 168, 0, 53);    //ipaddress of this ethernet
    EthernetClient client;               
    char inChar;                      //for reading bytes received from the server
    String inputString = "";    
    int cleaning_state=0;             //for getting the mode selected
    int firstcomma=0,secondcomma=0;   //for separating data
    SimpleTimer timer;              //for timer
    int received_full_string=0;       //to indicate where full data is recieved or not where 0= partial data 1= full data
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(9, OUTPUT);
      digitalWrite(9, LOW);
      Ethernet.begin(mac, ip);
      delay(1000);
      if (client.connect(server, 23)) // if client is connected on server 24
      {
        Serial.write("como");
      }
      else
      {
        Serial.write("disconn");
      }
     //cal a timer every 1s
      timer.setInterval(1000, RepeatTask);
    }
    void loop() {  
         timer.run(); //start the timer
       //chek if client is connected if not than try to reconnect otherwise read data from it
       if (client.connected())
          {
            client.print("R%");        //for handshaking
            while(client.available()>0) 
            {
              inChar = (char)client.read(); 
               inputString += inChar;           //concat for string
              if(inChar == '%') 
              {
                Serial.println(inputString);  
                received_full_string=1;   //indicating full data is recieved
                digitalWrite(9, HIGH); // blink the led if received full data  
               // further processing
              }          
            }
            delay(10);
          }
          else
          {
              client.stop();
  Serial.write("disconnected");
              delay(10);
              if (client.connect(server, 23))
              {
                Serial.write("re-connected");
              }
         }
            delay(100);
            //if full data is received than while exiting the loop make led turn off 
            if(received_full_string == 1)
            {
               digitalWrite(9, LOW);
            }
            inputString="";
    }
    //when timer is called check if the full data is received if yes than make the received_full_string=0 if no than stop the process
    void RepeatTask()
    {
      if(received_full_string == 1)
      {
        received_full_string=0;   
      }
      else
      {
        Serial.println("stop");
        digitalWrite(9, HIGH);
      }
    }

任何形式的帮助都将不胜感激。感谢

c#多个tcpclient使其中一个客户端断开连接几秒钟

问题解决了它既不是c#代码,也不是arduino代码错误——它是mac地址。每个arduino以太网都需要有唯一的ip和mac地址