在做一个需要与下位机网络通信的项目,用TCP通信方式,一帧一帧的传输数据,即,上位机发送一帧,如果正确,下位机回复一帧,上位机收到之后判断正确性,如果正确就写入数据库,否则重新发送请求。但是因为实时性要求比较强,发送数据之后要求不要有延时,但是如果没有延时的话,接收数据的线程还没有接收到数据,上位机就已经开始判断并重发。以前没有做过网络编程,不知道该如何处理。请大家帮忙看一下,谢谢!下面是发送线程的代码
/// <summary>
/// 发送搜索指令线程
/// </summary>
private void OrderProccess()
{
try
{
while (m_flag)
{
m_rStr = null;
//构造字节数组
Byte[] sendByte;
for (int k = 0; k < m_clist.Count; k++)
{ //是否这个服务器内的设备IP号
if (m_clist[k].m_name.Contains(m_name))
//起始位和IP号
{
// string datastr;
if (!m_dataflag)
{
sendByte = m_clist[k].orderbyte;
//datastr = "AA" + m_clist[k].ip.ToString("X2");
}
else
{
//是否是已经搜索到的设备
if (m_clist[k].isFound)
{
sendByte = m_clist[k].databyte;
//datastr = "A3" + m_clist[k].ip.ToString("X2");
}
else return;
} //向每个设备最多发三次命令
for (int i = 0; i <= 3; i++)
{
if (!m_dataflag)
{
//如果接收到的数据包与发送的不一致,重新发送
if (!(Compare(m_rStr, m_clist[k].osendStr)) || m_rStr == null)
{
if (i < 3)
{
m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
ts1 = new TimeSpan(DateTime.Now.Ticks);
//receiveTd = new Thread(new ThreadStart(ReceieveProccess));
//receiveTd.Start(); //启动线程用于接收数据
//每次发送之后延时100毫秒
// Thread.Sleep(1000);
}
else
{
//如果三次都没有返回从IP列表中删除
// m_clist.Remove(m_clist[k]);
m_clist[k].isFound = false;
break;
}
}
//接收到相同的数据包,设备搜索成功
else
{
//搜索到的设备个数加1
ipcount++;
m_clist[k].isFound = true;
m_clist[k].m_name = m_name + "_" + m_clist[k].ip.ToString();
//更新设备表
UpDateDevice(m_da, m_clist[k].ip.ToString("X2"));
break; }
}
else
{
if (m_rStr != null && m_rStr.Contains(m_clist[k].dsendStr.Substring(0, 4)))
{ //校验码校验数据是否正确 if (CRCKey_RTU(m_rStr) == 0)
{
//位移数据
if (m_type == 1)
{
//与之前的记录相比较,是否有变化,如果相同,不写入数据库
if (!Compare(m_rStr, m_clist[k].recordStr))
{
//接收到的数据写入数据库
WriteDB(m_da, m_rStr);
m_clist[k].recordStr = m_rStr;
}
else break;
}
else
{
//压力数据写入数据库
}
break;
}
}
else
{
if (i < 3)
{
m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
// Thread.Sleep(100);
}
else
{
break;
}
}
}
}
}
}
if (!m_dataflag)
{ //提示实际找到的设备
MessageBox.Show(m_ip.ToString() + "下搜索到" + ipcount + "个设备!");
//计数器清零
ipcount = 0;
Thread.Sleep(Timeout.Infinite);
}
//else
//线程挂起
// Thread.Sleep(Timeout.Infinite);
//break; }
}
catch (Exception ex)
{ //MessageBox.Show(ex.ToString());
// MessageBox.Show("连接已断开!"); }
finally
{
}
}接收: /// <summary>
/// 接收数据
/// </summary>
private void ReceieveProccess()
{
if (m_socket.Connected)
{
while (m_flag)
{
byte[] receiveByte = new byte[8];//表示通过套接字一次接收的数据长度
try
{
//接收长度为recvBytes.Length接收并将数据放进recvBytes中。参数0表示指定的传输控制方式,0就表示没有特殊行为。
m_socket.Receive(receiveByte, receiveByte.Length, 0);
//转换成16进制字符串
string strInfo = byteToHexStr(receiveByte);
//判断是否正常数据
if (strInfo.StartsWith("A"))
//收到的是回发的命令包
{
ts2 = new TimeSpan(DateTime.Now.Ticks);
TimeSpan ts = ts2.Subtract(ts1).Duration();
string spanTotalSeconds = ts.TotalSeconds.ToString(); //执行时间的总秒数 Console.WriteLine(spanTotalSeconds);
if (strInfo.Substring(0, 2) == "AA")
{
m_rStr = strInfo.Substring(0, 8); }
else //收到的是数据包
{
m_rStr = strInfo.Substring(0, 16);
}
}
}
catch (Exception ex)
{
//只有在非人为断开时才提示
if (!isclosing)
{
MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接" + ex.ToString());
//MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接");
}
m_success = false; break;
}
finally
{
}
} }
}
/// <summary>
/// 发送搜索指令线程
/// </summary>
private void OrderProccess()
{
try
{
while (m_flag)
{
m_rStr = null;
//构造字节数组
Byte[] sendByte;
for (int k = 0; k < m_clist.Count; k++)
{ //是否这个服务器内的设备IP号
if (m_clist[k].m_name.Contains(m_name))
//起始位和IP号
{
// string datastr;
if (!m_dataflag)
{
sendByte = m_clist[k].orderbyte;
//datastr = "AA" + m_clist[k].ip.ToString("X2");
}
else
{
//是否是已经搜索到的设备
if (m_clist[k].isFound)
{
sendByte = m_clist[k].databyte;
//datastr = "A3" + m_clist[k].ip.ToString("X2");
}
else return;
} //向每个设备最多发三次命令
for (int i = 0; i <= 3; i++)
{
if (!m_dataflag)
{
//如果接收到的数据包与发送的不一致,重新发送
if (!(Compare(m_rStr, m_clist[k].osendStr)) || m_rStr == null)
{
if (i < 3)
{
m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
ts1 = new TimeSpan(DateTime.Now.Ticks);
//receiveTd = new Thread(new ThreadStart(ReceieveProccess));
//receiveTd.Start(); //启动线程用于接收数据
//每次发送之后延时100毫秒
// Thread.Sleep(1000);
}
else
{
//如果三次都没有返回从IP列表中删除
// m_clist.Remove(m_clist[k]);
m_clist[k].isFound = false;
break;
}
}
//接收到相同的数据包,设备搜索成功
else
{
//搜索到的设备个数加1
ipcount++;
m_clist[k].isFound = true;
m_clist[k].m_name = m_name + "_" + m_clist[k].ip.ToString();
//更新设备表
UpDateDevice(m_da, m_clist[k].ip.ToString("X2"));
break; }
}
else
{
if (m_rStr != null && m_rStr.Contains(m_clist[k].dsendStr.Substring(0, 4)))
{ //校验码校验数据是否正确 if (CRCKey_RTU(m_rStr) == 0)
{
//位移数据
if (m_type == 1)
{
//与之前的记录相比较,是否有变化,如果相同,不写入数据库
if (!Compare(m_rStr, m_clist[k].recordStr))
{
//接收到的数据写入数据库
WriteDB(m_da, m_rStr);
m_clist[k].recordStr = m_rStr;
}
else break;
}
else
{
//压力数据写入数据库
}
break;
}
}
else
{
if (i < 3)
{
m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
// Thread.Sleep(100);
}
else
{
break;
}
}
}
}
}
}
if (!m_dataflag)
{ //提示实际找到的设备
MessageBox.Show(m_ip.ToString() + "下搜索到" + ipcount + "个设备!");
//计数器清零
ipcount = 0;
Thread.Sleep(Timeout.Infinite);
}
//else
//线程挂起
// Thread.Sleep(Timeout.Infinite);
//break; }
}
catch (Exception ex)
{ //MessageBox.Show(ex.ToString());
// MessageBox.Show("连接已断开!"); }
finally
{
}
}接收: /// <summary>
/// 接收数据
/// </summary>
private void ReceieveProccess()
{
if (m_socket.Connected)
{
while (m_flag)
{
byte[] receiveByte = new byte[8];//表示通过套接字一次接收的数据长度
try
{
//接收长度为recvBytes.Length接收并将数据放进recvBytes中。参数0表示指定的传输控制方式,0就表示没有特殊行为。
m_socket.Receive(receiveByte, receiveByte.Length, 0);
//转换成16进制字符串
string strInfo = byteToHexStr(receiveByte);
//判断是否正常数据
if (strInfo.StartsWith("A"))
//收到的是回发的命令包
{
ts2 = new TimeSpan(DateTime.Now.Ticks);
TimeSpan ts = ts2.Subtract(ts1).Duration();
string spanTotalSeconds = ts.TotalSeconds.ToString(); //执行时间的总秒数 Console.WriteLine(spanTotalSeconds);
if (strInfo.Substring(0, 2) == "AA")
{
m_rStr = strInfo.Substring(0, 8); }
else //收到的是数据包
{
m_rStr = strInfo.Substring(0, 16);
}
}
}
catch (Exception ex)
{
//只有在非人为断开时才提示
if (!isclosing)
{
MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接" + ex.ToString());
//MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接");
}
m_success = false; break;
}
finally
{
}
} }
}
恩,硬件方面现在已经确定了,但是做下位机的同事说如果我这边延时的话他那里会有问题。我在网上看了很多有关中断线程方面的资料还是很糊涂,他的意思是我不延时,每次都等到数据到了再中断发送数据的线程来完成整个过程。