使用socket 与西门子PLC仿真通讯时,连接plc没有问题,读取数据时报错:远程主机强迫关闭了一个现有的连接。
定位到代码 tcpClient.Receive(buffer, SocketFlags.None);
相关截图
相关代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.DataConvertLib;
using xktComm;
namespace FrmLogin
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
SiemensS7 s7 = new SiemensS7();
//取消跨线程访问问题
Control.CheckForIllegalCrossThreadCalls = false;
}
//声明一个socket对象
Socket tcpClient;
//创建取消数据源
private CancellationTokenSource cts;//= new CancellationTokenSource();
bool isConn;
///
/// 连接PLC
///
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Conn_Click(object sender, EventArgs e)
{
if (this.btn_Conn.Text == "连接")
{
//实例化
tcpClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
cts = new CancellationTokenSource();
EndPoint ep = new IPEndPoint(IPAddress.Parse(txtb_IPAddress.Text), int.Parse(txtb_Port.Text));
try
{
tcpClient.Connect(ep);
this.btn_Conn.Text = "断开";
this.btn_Conn.BackColor = Color.Green;
isConn = true;
}
catch (Exception ex )
{
ShowMessage("连接失败:" + ex.Message);
return;
}
Task.Run(new Action(() =>
{
GetPLCValue();
}));
}
else
{
tcpClient?.Close();
cts.Cancel();
isConn = false;
this.btn_Conn.Text = "连接";
this.btn_Conn.BackColor = DefaultBackColor;
}
}
int i = 0;
private void GetPLCValue()
{
while (isConn)//(!cts.IsCancellationRequested)
{
Thread.Sleep(10);
byte[] buffer = new byte[200];
int length = -1;
try
{
length = tcpClient.Receive(buffer,SocketFlags.None);
}
catch (Exception ex)
{
// i += 1;
ShowMessage("本次数据读取失败:" + ex.Message);
}
if (length == 20 )
{
byte[] result = thinger.DataConvertLib.ByteArrayLib.GetByteArrayFromByteArray(buffer,0,length);
float aa = thinger.DataConvertLib.FloatLib.GetFloatFromByteArray(result, 0, DataFormat.ABCD);
txtsh_data.VarValue = aa.ToString();
}
}
}
///
/// 清空显示信息
///
/// <param name="sender"></param>
/// <param name="e"></param>
private void Btn_Clear_Click(object sender, EventArgs e)
{
this.txtb_Message.Clear();
i = 0;
}
private void ShowMessage(string str)
{
if (!txtb_Message.Text.Contains(str))
{
txtb_Message.AppendText(str + "\r\n");
}
}
private void Button1_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[200];
int length = -1;
try
{
length = tcpClient.Receive(buffer, SocketFlags.None);
}
catch (Exception ex)
{
i += 1;
ShowMessage("本次数据读取失败:" + (i).ToString() + "次:" + ex.Message);
}
if (length == 20)
{
byte[] result = thinger.DataConvertLib.ByteArrayLib.GetByteArrayFromByteArray(buffer, 0, length);
float aa = thinger.DataConvertLib.FloatLib.GetFloatFromByteArray(result, 0, DataFormat.ABCD);
// ShowMessage(aa.ToString());
}
}
}
}
使用网口助手和PLC进行通讯正常,使用网口助手做服务器,C#程序做客户端也能正常通讯,但是使用C#程序做客户端访问plc服务器时报错。