唐山轨道机控制端TCP服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
6.7 KiB

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Net;
namespace EGFramework{
public class EGTCPClient : IModule, IEGFramework, IProtocolSend, IProtocolReceived
{
public Dictionary<string,TcpClient> TCPClientDevices { set; get; } = new Dictionary<string, TcpClient>();
public string ErrorLogs { set; get; }
public Encoding StringEncoding { set; get; } = Encoding.UTF8;
public Queue<ResponseMsg> ResponseMsgs { set; get; } = new Queue<ResponseMsg>();
public void Init()
{
this.EGRegisterSendAction(request=>{
if(request.protocolType == ProtocolType.TCPClient){
if(request.req.ToProtocolData() != null && request.req.ToProtocolData() != ""){
this.SendStringData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolData());
}
if(request.req.ToProtocolByteData() != null && request.req.ToProtocolByteData().Length > 0){
this.SendByteData(request.sender.GetHostByIp(),request.sender.GetPortByIp(),request.req.ToProtocolByteData());
}
}
});
}
/// <summary>
/// Connect Tcp client to server with check if target server is listened.
/// </summary>
public async Task<bool> ConnectTCP(string host,int port){
try{
if(!TCPClientDevices.ContainsKey(host + ":" + port)){
TcpClient tcpClient = new TcpClient();
await tcpClient.ConnectAsync(host,port);
//Print("Connect Tcp success in "+tcpClient.Client.RemoteEndPoint.ToString());
TCPClientDevices.Add(host + ":" + port,tcpClient);
_ = HandleClientAsync(tcpClient,host,port);
}else{
if(!TCPClientDevices[host + ":" + port].Connected){
await TCPClientDevices[host + ":" + port].ConnectAsync(host,port);
_ = HandleClientAsync(TCPClientDevices[host + ":" + port],host,port);
}
}
return true;
}
catch(Exception e){
ErrorLogs = "[open port error]" + e.ToString();
return false;
}
}
/// <summary>
/// Disconnect Tcp client to server.
/// </summary>
public void DisconnectTCP(string host,int port){
if(TCPClientDevices.ContainsKey(host + ":" + port)){
if (TCPClientDevices[host + ":" + port].Connected)
{
TCPClientDevices[host + ":" + port].Close();
TCPClientDevices.Remove(host + ":" + port);
}
}else{
//Not found in TCPClientDevices,need add?
}
}
public void SetEncoding(Encoding textEncoding)
{
this.StringEncoding = textEncoding;
}
public async void SendByteData(string host,int port,byte[] data){
// if serial port not open,open first
try{
bool result = await ConnectTCP(host,port);
if(result){
await TCPClientDevices[host + ":" + port].GetStream().WriteAsync(data,0,data.Length);
}
}catch(Exception e){
ErrorLogs = "[write error]" + e.ToString();
}
}
public void SendByteData(string destination,byte[] data){
SendByteData(destination.GetHostByIp(),destination.GetPortByIp(),data);
}
public void SendByteDataOnce(string host,int port,byte[] data){
SendByteData(host,port,data);
DisconnectTCP(host,port);
}
public void SendStringData(string host,int port,string str){
SendByteData(host,port,StringEncoding.GetBytes(str));
}
public void SendStringData(string destination,string data){
SendStringData(destination.GetHostByIp(),destination.GetPortByIp(),data);
}
public void SendStringDataOnce(string host,int port,string str){
SendStringData(host,port,str);
DisconnectTCP(host,port);
}
public Queue<ResponseMsg> GetReceivedMsg()
{
return ResponseMsgs;
}
/// <summary>
/// UpdateStatus
/// </summary>
public async void CheckAndRelink(){
foreach(TcpClient tcpClient in TCPClientDevices.Values){
if(!tcpClient.Connected){
await tcpClient.ConnectAsync((IPEndPoint)tcpClient.Client.RemoteEndPoint);
}
}
}
public async Task HandleClientAsync(TcpClient client,string host,int port)
{
try
{
NetworkStream stream = client.GetStream();
string ClientName = host+":"+port;
while (true)
{
byte[] buffer = new byte[1024];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
break;
}
string data = StringEncoding.GetString(buffer, 0, bytesRead);
byte[] receivedByte = new byte[bytesRead];
Array.Copy(buffer, 0, receivedByte, 0, bytesRead);
ResponseMsg receivedMsgs = new ResponseMsg(data,receivedByte,ClientName, ProtocolType.TCPClient);
ResponseMsgs.Enqueue(receivedMsgs);
//this.EGOnReceivedData(receivedMsgs);
}
DeleteClient(client,host,port);
}
catch (Exception)
{
}
}
public void DeleteClient(TcpClient client,string host,int port)
{
client.Close();
string clientName = host+":"+port;
if (TCPClientDevices.ContainsKey(clientName)) {
TCPClientDevices.Remove(clientName);
}
}
public IArchitecture GetArchitecture()
{
return EGArchitectureImplement.Interface;
}
}
public static class CanGetEGTCPClientExtension{
public static EGTCPClient EGTCPClient(this IEGFramework self){
return self.GetModule<EGTCPClient>();
}
public static TcpClient EGGetTCPClient(this IEGFramework self,string host,int port){
return self.GetModule<EGTCPClient>().TCPClientDevices[host + ":" + port];
}
}
}