c#multiple tcpclients使其中一个客户端断开几秒钟

时间:2015-11-30 05:49:04

标签: c# wpf tcp arduino ethernet

我正在尝试制作一个机器人。我需要大约6个arduino以太网连接到连接到计算机的思科集线器。我的c#代码是基于线程的,因此它可以处理多个客户端。工作完成后,服务器断开连接,然后客户端重新连接。客户端连接-disconnect-reconnect 100ms。在此,arduino以太网不断发送和接收数据。所有连接都在端口23上进行。每个客户端都有不同的ipaddress。

问题:

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

如果我将arduino代码的延迟从100ms增加到400ms,所有这些都得到连接n工作正常。但对于我的机器人过程,我需要它在100ms工作。

我无法弄清楚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的帮助下,我知道它是否接收数据。如果计时器没有从服务器获得数据,那么它会保持跟踪,然后它会保持指示灯亮起。否则它会闪烁。如果未连接到服务器,它将关闭。

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

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

1 个答案:

答案 0 :(得分:0)

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