socket怎样同时读、写下位机,以及同时读写出现界面卡死的问题,希望高手给解决一下,小弟在此谢过大家了

ssz1990 2015-05-01 09:50:56
我想用socket实现同时读、写下位机plc,代码如下,timer1实现时时读下位机,timer2实现实时写下位机,我为了满足同时读写,我在写到时候让读的timer1停止一下,写完了让timer1再次启动,结果界面卡死!请问各路大神怎样实现同时读写下位机
public void Receive()
{
List<byte> sendData = new List<byte>(255);

//[1].Send
sendData.AddRange(new Byte[] { 0, 0 });//1~2.(Transaction Identifier)
sendData.AddRange(new Byte[] { 0, 0 });//3~4:Protocol Identifier,0 = MODBUS protocol
sendData.AddRange(new Byte[] { 0, 6 });//5~6:后续的Byte数量(针对读请求,后续为6个byte)
sendData.Add(0);//7:Unit Identifier:This field is used for intra-system routing purpose.
sendData.Add(3);//8.Function Code : 3 (Read Multiple Register)
sendData.AddRange(new Byte[] { 0, 10 });//9~10.起始地址
sendData.AddRange(new Byte[] { 0, 4 });//11~12.需要读取的寄存器数量

this.Write(sendData.ToArray()); //发送读请求

//[2].防止连续读写引起前台UI线程阻塞
Application.DoEvents();

//[3].读取Response Header : 完后会返回8个byte的Response Header
byte[] receiveData = this.Read(25);//缓冲区中的数据总量不超过256byte,一次读256byte,防止残余数据影响下次读取

}
public void Write(byte[] data)
{

this.socket.Send(data);

}

short m, l, k;

public byte[] Read(int length)
{

byte[] data = new byte[length];
this.socket.Receive(data);

m = data[11] ;
m <<= 8;
l = data[12];
k = (short)(m + l);
if (data[7] == 3)
{
textBox3.Text = k.ToString();
}
return data;
}
private void button1_Click(object sender, EventArgs e)
{

timer1.Start();

}
public void Send()
{
List<byte> values = new List<byte>(255);
values.AddRange(new Byte[] { 95, 0 });//1~2.(Transaction Identifier)
values.AddRange(new Byte[] { 0, 0 });//3~4:Protocol Identifier,0 = MODBUS protocol
values.AddRange(new Byte[] { 0, 11 });//5~6:后续的Byte数量 data.Length +
values.Add(2);//7:Unit Identifier:This field is used for intra-system routing purpose.
values.Add((byte)16);//8.Function Code : 16 (Write Multiple Register)
values.AddRange(new Byte[] { 0, 0 });//9~10.起始地址
values.AddRange(new Byte[] { 0, 2 });//11~12.寄存器数量
values.Add((byte)4);//13.数据的Byte数量
byte qq,ww;
ushort a1;
a1 = Convert.ToUInt16(textBox4.Text);
qq = (byte)(a1 >> 8);
ww = (byte)(a1);
//[2].增加数据
values.AddRange(new Byte[] { qq ,ww ,0,4 });//14~End:需要发送的数据
//[3].写数据
this.Write(values.ToArray());
//[4].防止连续读写引起前台UI线程阻塞
Application.DoEvents();

//[5].读取Response: 写完后会返回12个byte的结果
byte[] responseHeader = this.Read(25);

}
private void timer1_Tick(object sender, EventArgs e)
{
Receive();
}
private void timer2_Tick(object sender, EventArgs e)
{
timer1.Stop();
Send();
timer1.Start();
//Thread.Sleep(1);
}

private void button3_Click(object sender, EventArgs e)
{
timer2.Start();
}

private void button4_Click(object sender, EventArgs e)
{
Connect();
}
...全文
182 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Forty2 2015-05-01
  • 打赏
  • 举报
回复
粗略一看问题比较多,但最主要的可能是你的通讯协议的误解。 从你发送和接收的代码猜测,‘下位机’的通讯是一问一答的方式(这种方式本事很好,简单和健壮)。 这种情况下,问和答是不能错开。而你的代码却不能保证这点。如下简写你的代码: Receive() { 发问1(); Application.DoEvents(); 收答1(); } Send() { 发问2(); Application.DoEvents(); 收答2(); } 可以看到你的代码没有进行同步的处理。更糟糕的是Application.DoEvents带来了更多的错位 。 因为Application.DoEvents使得定时器事件有机会得到执行,因此你的代码变成: 发问1(); timer2_Tick(...); 收答1(); 展开后变成: 发问1(); 发问2(); 收答2(); 收答1(); 也就是说, ‘收答2()’收到的是‘发问1’的答案,出现错位!更严重的是: '收答2()'不仅收走'发问1()'的答案,它也很可能一并收走‘发问2()’的答案。 结果就是 最后的'收答1()'收不到任何东西,并进入等待阻塞,从而界面卡死。
ssz1990 2015-05-01
  • 打赏
  • 举报
回复
引用 1 楼 Forty2 的回复:
粗略一看问题比较多,但最主要的可能是你的通讯协议的误解。 从你发送和接收的代码猜测,‘下位机’的通讯是一问一答的方式(这种方式本事很好,简单和健壮)。 这种情况下,问和答是不能错开。而你的代码却不能保证这点。如下简写你的代码: Receive() { 发问1(); Application.DoEvents(); 收答1(); } Send() { 发问2(); Application.DoEvents(); 收答2(); } 可以看到你的代码没有进行同步的处理。更糟糕的是Application.DoEvents带来了更多的错位 。 因为Application.DoEvents使得定时器事件有机会得到执行,因此你的代码变成: 发问1(); timer2_Tick(...); 收答1(); 展开后变成: 发问1(); 发问2(); 收答2(); 收答1(); 也就是说, ‘收答2()’收到的是‘发问1’的答案,出现错位!更严重的是: '收答2()'不仅收走'发问1()'的答案,它也很可能一并收走‘发问2()’的答案。 结果就是 最后的'收答1()'收不到任何东西,并进入等待阻塞,从而界面卡死。
怎样进行同步处理呢?能具体说一下吗?
abutwang 2015-05-01
  • 打赏
  • 举报
回复
同时读写时可以的,只要下位机支持的化,做的好点你可以研究下异步通信 然后置于界面卡死,你可以看下BackgroudWorker这个类,应该对你有帮助
ssz1990 2015-05-01
  • 打赏
  • 举报
回复
实现同步处理用线程的方法吗?启用线程是否可以保留 Application.DoEvents()?因为我看网上说Application.DoEvents()可以防止 { 发问1(); Application.DoEvents(); 收答1(); } 这种模式的堵塞
ssz1990 2015-05-01
  • 打赏
  • 举报
回复
那我应该怎样处理这种情况呢?怎样按照你说的进行同步处理?

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧