我可以发送UDP数据包,而不是接收UDP数据包.但是我怎么能发送UDP数据包,而不是在C#中不断接收UDP数据包

本文关键字:UDP 数据包 我可以 怎么能 | 更新日期: 2023-09-27 18:28:48

我正在使用PICO PT-104数据记录仪和三个温度探头PT 100。我试图通过在 UDP 数据包中发送命令来从中获取测量值。

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

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

PICO PT-104数据记录仪编程指南(第14页以太网协议(:

如果 l 将接收进程移动到单独的线程,则得到异常"通常只允许每个套接字地址(协议/网络地址/端口(使用一次"。

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

班级形式1:

     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;
    }
    // ######################################################################################################
}

类 UdpState:

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

我可以发送UDP数据包,而不是接收UDP数据包.但是我怎么能发送UDP数据包,而不是在C#中不断接收UDP数据包

停止为每个线程创建新UdpClient,并在应用程序的生命周期内使用相同的。

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

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次的循环,它工作正常。但是,当我单击连接按钮时,程序会等到方法sendStartReceiving((完成,然后在文本框中显示文本,我想避免这种情况。我想在单独的线程中接收消息,以便我的应用程序在接收 UDP 数据包时不会停止。

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

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