我可以发送UDP数据包而不是接收UDP数据包。但是如何发送UDP数据包而不是在C#中不断接收UDP数据包?

时间:2016-01-04 09:41:50

标签: c# udp

我正在使用带有三个温度探测器PT 100的PICO PT-104数据记录器。我试图通过UDP数据包发送命令来测量它。

首先, l发送消息“lock”,它将数据记录器锁定到我的笔记本电脑,因此如果数据记录器从网络上的其他人那里收到消息,它就不会回答。我得到了“锁定成功”的答案。之后,有必要发送“keep alive”命令,十六进制0x34。如果在锁定命令后10s未发送keep-alive命令,则数据记录器将自动从我的机器解锁,并且l将无法再次通信。我为此创建了计时器。

另一方面,我需要发送“开始转换”命令。当我发送该命令时,我得到答案“转换”和一些奇怪的字符(我期待数字)。在该命令之后,l应每720ms从所有4个通道获得测量值。

PICO PT-104数据记录器的程序员指南(第14页以太网协议):

如果l将接收进程移到单独的线程l获得异常“通常只允许使用每个套接字地址(协议/网络地址/端口)”。

https://www.picotech.com/download/manuals/USBPT104ProgrammersGuide.pdf

Class Form1:

     public partial class Form1 : Form
{
    int port = 1;
    String IPAddr = "10.1.52.155";
    private Thread tRead;
    public static bool messageReceived = false;

    public Form1()
    {
        InitializeComponent();
        timerKeepAlive(5);
        tRead = new Thread(new ThreadStart(ReceiveMessages));
        tRead.IsBackground = true;
        // tRead.Start();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        sendString("lock");
        sendStartConverting();
        //sendReadEPROM();

    }


    // *************************************** T I M E R ****************************************************

    private void timerKeepAlive(int seconds)
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = seconds * 1000;
        aTimer.Enabled = true;
    }

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        // keep alive se mora slati kao hex vrednost 0x34
        sendKeepAlive();
    }
    // ######################################################################################################


    // ************************************** S E N D I N G ****************************************************
    private void sendString(string message)
    {
        try
        {
            UdpClient udpClient = new UdpClient(1);

            //Povezivanje sa klijentom
            udpClient.Connect(IPAddress.Parse(IPAddr), port);

            // Pretvaranje poruke za slanje u  niz bajtova
            Byte[] sendBytes = Encoding.ASCII.GetBytes(message);

            // Slanje poruke
            udpClient.Send(sendBytes, sendBytes.Length);

            // Dodavanje poslate poruke u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Sent: " + message + "!");
                txtCH1.AppendText(Environment.NewLine);
            }));
            /*
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 55056);

            // Pretvaranje podataka koji su stigli u string
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Dodavanje podataka koji su stigli u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Arrived: " + returnData.ToString());
                txtCH1.AppendText(Environment.NewLine);
            }));
            */
            udpClient.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("ERROR: " + e.Message);
        }
    }

    private void sendKeepAlive()
    {
        try
        {
            UdpClient udpClient = new UdpClient(1);

            //Povezivanje sa klijentom
            udpClient.Connect(IPAddress.Parse(IPAddr), port);

            // Pretvaranje poruke za slanje u  niz bajtova
            var sendBytes = new byte[] { 0x34 };

            // Slanje poruke
            udpClient.Send(sendBytes, sendBytes.Length);

            // Dodavanje poslate poruke u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Sent: 0x34 Keep alive!");
                txtCH1.AppendText(Environment.NewLine);
            }));
            /*
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 55056);

            // Pretvaranje podataka koji su stigli u string
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Dodavanje podataka koji su stigli u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Arrived: " + returnData.ToString());
                txtCH1.AppendText(Environment.NewLine);
            }));
            */
            udpClient.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("ERROR: " + e.Message);
        }
    }

    private void sendStartConverting()
    {
        try
        {
            UdpClient udpClient = new UdpClient(1);

            //Povezivanje sa klijentom
            udpClient.Connect(IPAddress.Parse(IPAddr), port);

            // Pretvaranje poruke za slanje u  niz bajtova
            int num = 0x310F;
            var unum = (uint)num;    // Convert to uint for correct >> with negative numbers
            var sendBytes = new[] {
            (byte)(unum >> 8),
            (byte)(unum)
            };

            // Slanje poruke
            udpClient.Send(sendBytes, sendBytes.Length);

            // Dodavanje poslate poruke u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Sent: 0x310F Start converting!");
                txtCH1.AppendText(Environment.NewLine);
            }));

            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 55056);

            // Pretvaranje podataka koji su stigli u string
            for (int i = 0; i < 10; i++)
            {
                Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
                string returnData = Encoding.ASCII.GetString(receiveBytes);
                Encoding e = Encoding.GetEncoding(returnData);
                // Dodavanje podataka koji su stigli u textBox
                this.txtCH1.Invoke((Action)(() =>
                {
                    txtCH1.AppendText("Arrived: " + returnData);
                    txtCH1.AppendText(Environment.NewLine);
                }));
            }

            udpClient.Close();

        }
        catch (Exception e)
        {
            MessageBox.Show("ERROR: " + e.Message);
        }
    }

    private void sendReadEPROM()
    {
        try
        {
            UdpClient udpClient = new UdpClient(1);

            //Povezivanje sa klijentom
            udpClient.Connect(IPAddress.Parse(IPAddr), port);

            // Pretvaranje poruke za slanje u  niz bajtova
            var sendBytes = new byte[] { 0x32 };

            // Slanje poruke
            udpClient.Send(sendBytes, sendBytes.Length);

            // Dodavanje poslate poruke u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Sent: 0x32 Read EPROM!");
                txtCH1.AppendText(Environment.NewLine);
            }));
            /*
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 55056);

            // Pretvaranje podataka koji su stigli u string
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Dodavanje podataka koji su stigli u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Arrived: " + returnData.ToString());
                txtCH1.AppendText(Environment.NewLine);
            }));
            */
            udpClient.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show("ERROR: " + e.Message);
        }
    }

    private void sendUnlock()
    {
        try
        {
            UdpClient udpClient = new UdpClient(1);

            //Povezivanje sa klijentom
            udpClient.Connect(IPAddress.Parse(IPAddr), port);

            // Pretvaranje poruke za slanje u  niz bajtova
            var sendBytes = new byte[] { 0x33 };

            // Slanje poruke
            udpClient.Send(sendBytes, sendBytes.Length);

            // Dodavanje poslate poruke u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Sent: 0x33 Unlock!");
                txtCH1.AppendText(Environment.NewLine);
            }));
            /*
            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 55056);

            // Pretvaranje podataka koji su stigli u string
            Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Dodavanje podataka koji su stigli u textBox
            this.txtCH1.Invoke((Action)(() =>
            {
                txtCH1.AppendText("Arrived: " + returnData.ToString());
                txtCH1.AppendText(Environment.NewLine);
            }));
            */
            udpClient.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }



    // #######################################################################################################


    // *********************************** R E C E I V I N G ****************************************************

    private void ReceiveMessages()
    {
        try
        {
            // Receive a message and write it to the console.
            IPEndPoint e = new IPEndPoint(IPAddress.Any, port);
            UdpClient u = new UdpClient(e);

            UdpState s = new UdpState();
            s.e = e;
            s.u = u;

            Console.WriteLine("listening for messages");
            u.BeginReceive(new AsyncCallback(ReceiveCallback), s);

            // Do some work while we wait for a message. For this example,
            // we'll just sleep
            while (!messageReceived)
            {
                Thread.Sleep(100);
            }
        }
        catch (Exception e)
        {
            MessageBox.Show("ERROR: " + e.Message);
        }
    }

    public void ReceiveCallback(IAsyncResult ar)
    {
        UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
        IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;

        Byte[] receiveBytes = u.EndReceive(ar, ref e);
        string receiveString = Encoding.ASCII.GetString(receiveBytes);

        this.txtCH1.Invoke((Action)(() =>
        {
            txtCH1.AppendText("Arrived: " + receiveString);
            txtCH1.AppendText(Environment.NewLine);
        }));
        Console.WriteLine("Received: {0}", receiveString);
        messageReceived = true;
    }

    // ######################################################################################################
}

Class UdpState:

    class UdpState
{
    public IPEndPoint e;
    public UdpClient u;
}

2 个答案:

答案 0 :(得分:2)

停止为每个线程创建一个新的$eclipse_home/plugins并在应用程序的生命周期中使用相同的线程。

答案 1 :(得分:0)

我更正了代码,现在它看起来像这样:

public partial class Form1 : Form
{
    int portSend;
    int portReceive;
    String IPAddr;

    IPEndPoint RemoteIpEndPointReceive;
    IPEndPoint RemoteIpEndPointSend;

    UdpClient udpClientReceive; // ne treba
    UdpClient udpClientSend;
    UdpState udpState; // ne treba

    byte[] calibrationChannel1;
    byte[] calibrationChannel2;
    byte[] calibrationChannel3;
    byte[] calibrationChannel4;

    uint CH1;
    uint CH2;
    uint CH3;
    uint CH4;

    private bool startReceiving;

    private Thread tReceive;

    public Form1()
    {
        InitializeComponent();

        // Initialization of atributes
        Initialization();
    }

    private void Initialization()
    {
        // IPAddress and PORT number
        portSend = 1;
        portReceive = 55056;
        IPAddr = "10.1.52.155";

        // Timer for sending message keep-alive
        //timerKeepAlive(5);

        // IpEndPoint for receiving messages
        RemoteIpEndPointReceive = new IPEndPoint(IPAddress.Parse("10.1.52.155"), portReceive); 

        // IpEndPoint for sending messages
        RemoteIpEndPointSend = new IPEndPoint(IPAddress.Parse(IPAddr), portSend);

        // UdpClient for receiving messages
        udpClientReceive = new UdpClient();

        // UdpClient for sending messages
        udpClientSend = new UdpClient();

        udpState = new UdpState();

        // Calibration bytes from all 4 channels
        calibrationChannel1 = new byte[4]; 
        calibrationChannel2 = new byte[4];
        calibrationChannel3 = new byte[4];
        calibrationChannel4 = new byte[4];

        startReceiving = false;


        // Thread for receiving messages
        tReceive = new Thread(new ThreadStart(() => ReceiveMessages(udpClientSend)));
        tReceive.Start();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        btnStop.Enabled = false;
    }


    // *************************************** T I M E R ****************************************************

    private void timerKeepAlive(int seconds)
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = seconds * 1000;
        aTimer.Enabled = true;
    }

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        // Keep alive need to be sent as HEX value
        sendKeepAlive();
    }
    // ######################################################################################################


    // ************************************** S E N D I N G ****************************************************
    private void sendString(string message)
    {
        try
        {
            // Connecting with client
            udpClientSend.Connect(RemoteIpEndPointSend);

            // Converting message to array of bytes
            Byte[] sendBytes = Encoding.ASCII.GetBytes(message);

            // Sending message
            udpClientSend.Send(sendBytes, sendBytes.Length);

            // Adding sent message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Sent: " + message + "!");
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Receiving message
            Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

            // Converting received bytes to string
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Adding received message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Arrived: " + returnData.ToString());
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Closing connection with client
            //udpClientSend.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation
                            );
        }
    }

    private void sendKeepAlive()
    {
        try
        {
            // Connecting with client
            udpClientSend.Connect(RemoteIpEndPointSend);

            // Creating byte message
            var sendBytes = new byte[] { 0x34 };

            // Sending message
            udpClientSend.Send(sendBytes, sendBytes.Length);

            // Adding sent message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Sent: 0x34 Keep alive!");
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Receiving message
            Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

            // Converting received bytes to string
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Adding received message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Arrived: " + returnData.ToString());
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            //udpClientSend.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
        }
    }

    private void sendStartConverting()
    {
        try
        {
            // Connecting with client
            udpClientSend.Connect(RemoteIpEndPointSend);

            // Creating message as array of bytes
            int num = 0x310F;
            var unum = (uint)num;    // Convert to uint for correct >> with negative numbers
            var sendBytes = new[] {
            (byte)(unum >> 8),
            (byte)(unum)
            };

            // Sending message
            udpClientSend.Send(sendBytes, sendBytes.Length);

            // Adding sent message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Sent: 0x310F Start converting!");
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Receving new message 10 times
            //for (int i = 0; i < 20; i++)
            ///{
                // Receiving message
                Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

                // Conveting received bytes to string
                string returnData = ByteArrayToString(receiveBytes);

                // Start receving in thread
                startReceiving = true;

                /*
                // Adding received message to text box
                this.txtMeasurements.Invoke((Action)(() =>
                {
                    txtMeasurements.AppendText("Arrived: " + returnData);
                    txtMeasurements.AppendText(Environment.NewLine);
                }));
                */
            //}
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
        }
    }

    private void sendReadEPROM()
    {
        try
        {
            // Connecting with client
            udpClientSend.Connect(IPAddress.Parse(IPAddr), portSend);

            // Creating byte message
            var sendBytes = new byte[] { 0x32 };

            // Sending message
            udpClientSend.Send(sendBytes, sendBytes.Length);

            // Adding sent message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Sent: 0x32 Read EPROM!");
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Receiving message
            Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

            // Calibartion bytes CH1 - LSB first
            calibrationChannel1[0] = receiveBytes[37];
            calibrationChannel1[1] = receiveBytes[38];
            calibrationChannel1[2] = receiveBytes[39];
            calibrationChannel1[3] = receiveBytes[40];
            CH1 = (uint) byteArrayToDecimal(calibrationChannel1);

            // Calibartion bytes CH2 - LSB first
            calibrationChannel2[0] = receiveBytes[41];
            calibrationChannel2[1] = receiveBytes[42];
            calibrationChannel2[2] = receiveBytes[43];
            calibrationChannel2[3] = receiveBytes[44];
            CH2 = (uint) byteArrayToDecimal(calibrationChannel2);

            // Calibartion bytes CH3 - LSB first
            calibrationChannel3[0] = receiveBytes[45];
            calibrationChannel3[1] = receiveBytes[46];
            calibrationChannel3[2] = receiveBytes[47];
            calibrationChannel3[3] = receiveBytes[48];
            CH3 = (uint) byteArrayToDecimal(calibrationChannel3);

            // Calibartion bytes CH4 - LSB first
            calibrationChannel1[0] = receiveBytes[49];
            calibrationChannel1[1] = receiveBytes[50];
            calibrationChannel1[2] = receiveBytes[51];
            calibrationChannel1[3] = receiveBytes[52];
            CH4 = (uint) byteArrayToDecimal(calibrationChannel4);

            // Adding calibration data to text boxes
            Invoke((MethodInvoker)delegate
            {
                txtCH1.Text = CH1.ToString();
                txtCH2.Text = CH2.ToString();
                txtCH3.Text = CH3.ToString();
                txtCH4.Text = CH4.ToString();

                txtCH1hex.Text = ByteArrayToString(calibrationChannel1);
                txtCH2hex.Text = ByteArrayToString(calibrationChannel2);
                txtCH3hex.Text = ByteArrayToString(calibrationChannel3);
                txtCH4hex.Text = ByteArrayToString(calibrationChannel4);
            });

            // Converting received bytes to string
            string returnData = ByteArrayToString(receiveBytes);

            // Adding received message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Arrived: " + returnData.ToString());
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Closing connection with client
            //udpClientSend.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
        }
    }

    private void sendUnlock()
    {
        try
        {
            // Connecting with client
            udpClientSend.Connect(RemoteIpEndPointSend);

            // Creating byte message
            var sendBytes = new byte[] { 0x33 };

            // Sending message
            udpClientSend.Send(sendBytes, sendBytes.Length);

            // Adding sent message to text box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Sent: 0x33 Unlock!");
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Receiving message
            Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

            // Converting received bytes to string
            string returnData = Encoding.ASCII.GetString(receiveBytes);

            // Adding received message to tex box
            this.txtMeasurements.Invoke((Action)(() =>
            {
                txtMeasurements.AppendText("Arrived: " + returnData.ToString());
                txtMeasurements.AppendText(Environment.NewLine);
            }));

            // Closing connection with client
            //udpClientSend.Close();
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
        }
    }

    private string ByteArrayToString(byte[] ba)
    {
        string hex = BitConverter.ToString(ba);
        return hex.Replace("-", " ");
    }

    private int byteArrayToDecimal(byte[] ba)
    {
        if (BitConverter.IsLittleEndian)
            Array.Reverse(ba); //need the bytes in the reverse order
        return BitConverter.ToInt32(ba, 0);
    }

    // #######################################################################################################


    // *********************************** R E C E I V I N G ****************************************************

    private void ReceiveMessages(UdpClient client)
    {
        try
        {
            int available = client.Available;
            client.Connect(RemoteIpEndPointReceive);

            while(startReceiving)
            {
                // Receiving message
                Byte[] receiveBytes = udpClientSend.Receive(ref RemoteIpEndPointReceive);

                // Adding received message to text box
                this.txtMeasurements.Invoke((Action) (() => 
                {
                    txtMeasurements.AppendText("Arrived in thread: " + ByteArrayToString(receiveBytes));
                }));

            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message,
                            "Exception",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
        }
    }
    // ******************************************************************************************************

    private void btnConnect_Click(object sender, EventArgs e)
    {
        // Enabling stop button
        btnStop.Enabled = true;

        // Firstly we need to "lock" data logger to our machine
        sendString("lock");

        // Read the EEPROM to obtain calibration information for the channels
        sendReadEPROM();

        // Take measurements 0, 1, 2, 3 on channels 1, 2, 3, 4.
        // Note that measurements are stored MSB-first while calibration values 
        // are stored LSB - first.
        sendStartConverting();
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        startReceiving = false;
        btnStop.Enabled = false;
    }
}

在方法 sendStartConverting()中,我写了一个接收UDP数据包20次的循环,它运行正常。但是,当我点击 CONNECT 按钮程序等待,直到方法 sendStartReceiving()完成,然后文本显示在文本框中,我想避免这种情况。我想在单独的线程中接收消息,以便我的应用程序在接收UDP数据包时不会停止。

当我将接收进程移到单独的线程时,我的应用程序会阻塞。

有谁知道为什么?欢迎任何关于代码的建议。