在C#中,可以使用TcpClient类来创建一个TCP客户端,并接收字符串数据。在wpf mvvm框架下,我们创建一个ViewModel,在项目中添加类:
之后具体代码如下:
using Newtonsoft.Json;
using Prism.Commands;
using QZ.General;
using System;
using System.ComponentModel;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace JV_SFC.ViewModels
{
public class TCPClientViewmodel:BaseNotify
{
private TcpClient visionClient = null;
private int ErrorCount = 0;
private bool Vision_ThreadRunFlag = true;
private string _IpAddress = "127.0.0.1";
[Description("IP")]
public string IpAddress
{
get { return _IpAddress; }
set { SetProperty(ref _IpAddress, value); }
}
private int _port;
[Description("端口")]
public int port
{
get { return _port; }
set { SetProperty(ref _port, value); }
}
private bool _visionConnected = false;
[Description("是否为连接状态")]
[JsonIgnore]
public bool visionConnected
{
get { return _visionConnected; }
set { SetProperty(ref _visionConnected, value); }
}
private DelegateCommand _visionConnetion;
[JsonIgnore]
[Description("客户端连接命令")]
public DelegateCommand VisionConnetionCmd =>
_visionConnetion ?? (_visionConnetion = new DelegateCommand(ExecuteVisionConnetionCmd));
[Description("执行命令")]
void ExecuteVisionConnetionCmd()
{
Vision_ThreadRunFlag = true;
VisionClientInit(msg => { });
}
private DelegateCommand _Close;
[JsonIgnore]
[Description("断开客户端命令")]
public DelegateCommand VisionDisConnectedCmd =>
_Close ?? (_Close = new DelegateCommand(ExecuteCloseCommandName));
[Description("执行命令")]
void ExecuteCloseCommandName()
{
if (visionClient != null)
{
Vision_ThreadRunFlag = false;
visionClient.Close();
visionClient?.Dispose();
visionConnected = false;
}
}
/// <summary>
/// 初始化客户端
/// </summary>
/// <param name="ReceiveMsgCallback"></param>
public void VisionClientInit(Action<string> ReceiveMsgCallback)
{
Thread thread = new Thread(() =>
{
while (Vision_ThreadRunFlag)
{
try
{
if (ErrorCount > 70)
{
MessageBox.Show("TCP客户端长时间连接不上视觉软件,中断连接!!");
break;
}
if (!visionConnected)
{
visionClient = new TcpClient();
visionClient.Connect(IpAddress, port);
Console.WriteLine("TCP客户端初始化,连接OK!");
visionConnected = visionClient.Connected;
NetworkStream stream = visionClient.GetStream();
byte[] buffer = new byte[1024];
int bytesRead;
while (visionConnected && (bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
string responseData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
ReceiveMsgCallback(responseData);
ErrorCount = 0;
Thread.Sleep(5);
}
}
}
catch (Exception ex)
{
ErrorCount++;
visionConnected = false;
Console.WriteLine("异常:"+ex);
Task.Delay(1000);
}
}
});
thread.Start();
thread.IsBackground = true;
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public bool VisionClientSendData(string msg)
{
if (visionClient == null || !visionClient.Connected)
{
return false;
}
using (NetworkStream stream = visionClient.GetStream())
{
if (stream.CanWrite)
{
byte[] buffer = Encoding.UTF8.GetBytes(msg);
stream.Write(buffer, 0, buffer.Length);
}
}
return true;
}
}
}
代码通过不断从网络流中读取数据,这里做了断线重连的机制,可以在指定的时间退出。
当前端需要调用时,可以在前端绑定端口号和IP地址,Command绑定连接VisionConnetionCmd 和断开连接VisionDisConnectedCmd即可。