using HH.WCS.Mobox3.DoubleCoin.dispatch;
|
using HH.WCS.Mobox3.DoubleCoin.util;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Net;
|
using System.Net.Sockets;
|
using System.Text;
|
|
namespace HH.WCS.Mobox3.DoubleCoin.device
|
{
|
public class TcpServer
|
{
|
public TcpServer(string ip, int port)
|
{
|
Init(ip, port);
|
}
|
private void Init(string ip, int port)
|
{
|
//创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
|
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
try
|
{
|
//将该socket绑定到主机上面的某个端口,端口应该放到配置文件中
|
socket.Bind(new IPEndPoint(IPAddress.Parse(ip), port));
|
Console.WriteLine(port);
|
//启动监听,并且设置一个最大的队列长度
|
socket.Listen(30);
|
//开始接受客户端连接请求
|
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
|
}
|
catch (Exception e)
|
{
|
Console.WriteLine(e.Message);
|
}
|
}
|
public static Dictionary<string, Socket> clients = new Dictionary<string, Socket>();
|
public static Dictionary<string, byte[]> buffers = new Dictionary<string, byte[]>();
|
public static Dictionary<string,bool> isSend = new Dictionary<string, bool>();
|
public static Dictionary<string,bool> isCheck = new Dictionary<string, bool>();
|
|
public static Dictionary<string,int> saoMa = new Dictionary<string, int>();
|
|
public static void ClientAccepted(IAsyncResult ar)
|
{
|
|
var socket = ar.AsyncState as Socket;
|
var client = socket.EndAccept(ar);
|
string remote_ip = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString();
|
if (clients.Keys.Contains(remote_ip))
|
{
|
clients[remote_ip] = client;
|
}
|
else
|
{
|
clients.Add(remote_ip, client);
|
}
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
}
|
|
if (!isSend.Keys.Contains(remote_ip))
|
{
|
isSend.Add(remote_ip, false);
|
}
|
|
if (!isCheck.Keys.Contains(remote_ip))
|
{
|
isCheck.Add(remote_ip, false);
|
}
|
|
//给客户端发送一个欢迎消息
|
//client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at " + DateTime.Now.ToString()));
|
Console.WriteLine(remote_ip);
|
|
try
|
{
|
client.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"【接收客户端的消息异常】:" + ex.Message);
|
}
|
//准备接受下一个客户端请求
|
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
|
}
|
|
|
public static void ReceiveMessage(IAsyncResult ar)
|
{
|
try
|
{
|
var socket = ar.AsyncState as Socket;
|
string remote_ip = ((System.Net.IPEndPoint)socket.RemoteEndPoint).Address.ToString();
|
var length = socket.EndReceive(ar);
|
if (length == 0)
|
{
|
clients.Remove(remote_ip);
|
buffers.Remove(remote_ip);
|
isSend.Remove(remote_ip);
|
isCheck.Remove(remote_ip);
|
saoMa.Remove(remote_ip);
|
return;
|
}
|
else
|
{
|
if (!clients.Keys.Contains(remote_ip))
|
{
|
clients.Add(remote_ip, socket);
|
}
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
|
}
|
if (!isSend.Keys.Contains(remote_ip))
|
{
|
isSend.Add(remote_ip, false);
|
}
|
if (!isCheck.Keys.Contains(remote_ip))
|
{
|
isCheck.Add(remote_ip, false);
|
}
|
if (!saoMa.Keys.Contains(remote_ip))
|
{
|
saoMa.Add(remote_ip, 3);
|
}
|
}
|
|
//LogHelper.Info($"接收到信息,IP:{remote_ip},MSG:{BitConverter.ToString(buffers[remote_ip])}");
|
|
if (buffers.Keys.Contains(remote_ip))
|
{
|
var messageBytes = new byte[length];
|
Array.Copy(buffers[remote_ip], 0, messageBytes, 0, length);
|
|
try
|
{
|
//读卡器校验
|
var message = BitConverter.ToString(messageBytes);
|
|
if (!saoMa.ContainsKey(remote_ip))
|
{
|
saoMa.Add(remote_ip, 3);
|
}
|
if (messageBytes.Length <= 20 && messageBytes.Length > 0)
|
{
|
saoMa[remote_ip] = 3;//未扫到码
|
}
|
|
if (messageBytes.Length >= 21 && isCheck[remote_ip])
|
{
|
byte[] rfid = new byte[12];
|
Array.Copy(messageBytes, 9, rfid, 0, 12);
|
|
string rfids16 = BitConverter.ToString(rfid);
|
string rfids = Encoding.ASCII.GetString(rfid);
|
LogHelper.Info($"读卡器校验对应容器号:{rfids},其16进制形式:{rfids16}");
|
if (ScanCodeHelper.Analysis(remote_ip, rfids))//校验RFID
|
{
|
isCheck[remote_ip] = true;
|
saoMa[remote_ip] = 1;//扫码匹配
|
}
|
else
|
{
|
isCheck[remote_ip] = true;
|
saoMa[remote_ip] = 2;//扫码不匹配
|
}
|
}
|
else
|
{
|
LogHelper.Info($"不满足读卡器校验规定:IP:{remote_ip},MSG:{message}");
|
}
|
}
|
catch(Exception ex)
|
{
|
LogHelper.Info($"扫码校验发生了异常:{ex.Message}");
|
saoMa[remote_ip] = 4;//扫码异常
|
}
|
|
try
|
{
|
//卷帘门开关
|
var plc = Settings.SafeDoorDevices.FirstOrDefault(a => a.IPAddress == remote_ip);
|
var log = string.Join(",", messageBytes.Select(x => x.ToString()));
|
if (plc != null &&
|
messageBytes[0] == 0x3F &&
|
messageBytes[1] == 0x00 &&
|
messageBytes[2] == 0x11 &&
|
messageBytes[3] == 0x0d &&
|
messageBytes[4] == 0x0a && isSend[remote_ip])
|
{
|
LogHelper.Info($"{plc.DeviceName}设备开门完成,{log}");
|
|
var dic = new List<param>();
|
dic.Add(new param() { name = "From", value = "1" });
|
dic.Add(new param() { name = "To", value = plc.DeviceCode });
|
|
var resAgv = NDCApi.AddOrderNew(164, 1, System.DateTime.Now.Ticks.ToString(), dic);
|
LogHelper.Info($"通知AGV通过安全门,返回结果:{JsonConvert.SerializeObject(resAgv)}设备开门完成");
|
if (resAgv.err_code == 0)
|
{
|
isSend[remote_ip] = false;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"{remote_ip}设备返回:{log}");
|
}
|
}
|
catch(Exception ex)
|
{
|
LogHelper.Info($"卷帘门校验发生了异常:{ex.Message}");
|
}
|
//TcpServerSend(remote_ip, System.Text.Encoding.Default.GetBytes(msgSend));
|
Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer
|
}
|
else
|
{
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
}
|
}
|
|
//接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
|
socket.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
|
}
|
catch (Exception ex)
|
{
|
|
}
|
}
|
|
private static string GetHexString(byte[] buffer, int lenght)
|
{
|
return BitConverter.ToString(buffer, 0, lenght).Replace("-", string.Empty).ToLower();
|
}
|
|
public static bool TcpServerSend(string ip, byte[] msg)
|
{
|
if (clients.Keys.Contains(ip))
|
{
|
var client = clients[ip];
|
if (client.Connected)
|
{
|
try
|
{
|
client.Send(msg);
|
LogHelper.Info($"已发送给该AGV地址{ip},{msg}");
|
return true;
|
}
|
catch (SocketException ex)
|
{
|
LogHelper.Info(ex.Message, "Error");
|
clients[ip].Close();
|
clients.Remove(ip);
|
}
|
}
|
else
|
{
|
clients[ip].Close();
|
clients.Remove(ip);
|
}
|
}
|
else
|
{
|
LogHelper.Info("未找到该设备,是否已连接?");
|
}
|
return false;
|
|
}
|
|
}
|
}
|