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
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]; |
|
} |
|
} |
|
|
|
}
|
|
|