我可以发送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;
}
停止为每个线程创建新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 数据包时不会停止。
当我将接收进程移动到单独的线程时,我的应用程序会阻塞。
有谁知道为什么?欢迎任何关于代码的建议。