之前实现的检验虚拟盒子虽然实现了串口转TCP功能,但是缺乏设计,表现为设计太僵硬,只能固定两三种转换模式。而且随着转换增加复杂度太大。比如要实现某些仪器TCP不能跨网站做TCP直接跳板就难度大大增加。
虚拟盒子体现为代码力,这次体现为设计力。
源码
虚拟盒子如下: 新效果-TCP跳转示例 其他测试
为了解决设计不足导致的扩展困难,全新设计了超级转换器,分享初版代码。这次抽取了转换器接口,和提取了委托。实现为一个dll,方便其他exe快速引入。
拿串口端来说,本质就是1.监控串口发来的消息,然后转发出去。2.把其他端发来的消息推送到串口。
拿tcp端来说,本质就是1.监控tcp端发来的消息,然后转发出去。2.把其他端发来的消息转发给tcp。
默认实现了串口、tcp服务端、tcp客户端、udp服务端、udp客户端。也可以实现接口来实现读写文本,调用webservice等,只要是需要转发消息的都可。
抽取接口如下(所有的消息实现端实现该接口):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MessageSwitch
{
public interface IMessageSwitch
{
string GetTypeName();
string GetConfig();
bool SetConfig(string confStr);
bool SetPushDelegate(PushMessageToSwitch push, SwitchType type, WriteLog log);
bool Start();
bool Stop();
bool SendMessage(byte[] msgByteArr);
string GetReflectStr();
}
}
转换器及委托实现转换逻辑
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MessageSwitch
{
public enum SwitchType
{
In,
Out
}
public delegate bool PushMessageToSwitch(byte[] msgByteArr,SwitchType type);
public delegate void WriteLog(string msg);
public delegate void AddMessageSwitch(IMessageSwitch sw,SwitchType type);
public class SwitchMian
{
private List<IMessageSwitch> inList = new List<IMessageSwitch>();
private List<IMessageSwitch> outList = new List<IMessageSwitch>();
private PushMessageToSwitch PushMessage;
private WriteLog log;
public SwitchMian(WriteLog logW)
{
PushMessage = new PushMessageToSwitch(PushMessageToSwitchDo);
log = logW;
}
private bool PushMessageToSwitchDo(byte[] msgByteArr, SwitchType type)
{
string lineStr = System.Text.Encoding.Default.GetString(msgByteArr);
lineStr = Util.DealNotSeeToSeeChar(lineStr);
if (type == SwitchType.In)
{
if (outList != null && outList.Count > 0)
{
foreach (IMessageSwitch s in outList)
{
if (log != null)
{
log("输入->输出"+lineStr);
}
s.SendMessage(msgByteArr);
}
}
}
if (type == SwitchType.Out)
{
if (inList != null && inList.Count > 0)
{
foreach (IMessageSwitch s in inList)
{
if (log != null)
{
log("输出->输入" + lineStr);
}
s.SendMessage(msgByteArr);
}
}
}
return true;
}
public void AddToIn(IMessageSwitch obj)
{
if (log != null)
{
log(obj.GetTypeName()+"加入输入端");
}
obj.SetPushDelegate(PushMessage, SwitchType.In,log);
inList.Add(obj);
}
public void AddToOut(IMessageSwitch obj)
{
if (log != null)
{
log(obj.GetTypeName() + "加入输出端");
}
obj.SetPushDelegate(PushMessage, SwitchType.Out,log);
outList.Add(obj);
}
public string GetConfig()
{
List<ConfDto> confList = new List<ConfDto>();
if (inList != null && inList.Count > 0)
{
foreach (IMessageSwitch s in inList)
{
if (log != null)
{
log("获取:" + s.GetTypeName()+"配置");
}
ConfDto dto = new ConfDto();
dto.ConfStr = s.GetConfig();
dto.ReflectStr = s.GetReflectStr();
dto.Type = SwitchType.In;
confList.Add(dto);
}
}
if (outList != null && outList.Count > 0)
{
foreach (IMessageSwitch s in outList)
{
if (log != null)
{
log("获取:" + s.GetTypeName() + "配置");
}
ConfDto dto = new ConfDto();
dto.ConfStr = s.GetConfig();
dto.ReflectStr = s.GetReflectStr();
dto.Type = SwitchType.Out;
confList.Add(dto);
}
}
return Util.Serializer(confList.GetType(), confList);
}
public void LoadConfig(string confStr,AddMessageSwitch addSw)
{
List<ConfDto> confList = Util.XmlDeserialize<List<ConfDto>>(confStr, Encoding.Default);
if (confList != null && confList.Count > 0)
{
foreach (var v in confList)
{
if (v.Type == SwitchType.In)
{
object obj = GetObjectByReflectStr(v.ReflectStr);
if (obj != null)
{
IMessageSwitch swi = obj as IMessageSwitch;
if (swi != null)
{
swi.SetConfig(v.ConfStr);
if (log != null)
{
log("载入:" + swi.GetTypeName() + "对象到输入端");
}
AddToIn(swi);
if (addSw != null)
{
addSw(swi, SwitchType.In);
}
}
}
}
if (v.Type == SwitchType.Out)
{
object obj = GetObjectByReflectStr(v.ReflectStr);
if (obj != null)
{
IMessageSwitch swi = obj as IMessageSwitch;
if (swi != null)
{
swi.SetConfig(v.ConfStr);
if (log != null)
{
log("载入:" + swi.GetTypeName() + "对象到输出端");
}
AddToOut(swi);
if (addSw != null)
{
addSw(swi, SwitchType.Out);
}
}
}
}
}
}
}
public object GetObjectByReflectStr(string reflectStr)
{
try
{
if (log != null)
{
log("准备解析处理对象:" + reflectStr);
}
string[] strArr = reflectStr.Replace(" ", "").Split(',');
if (strArr.Length < 2)
{
if (log != null)
{
log("配置的处理对象错误,请采用类全名,动态库名");
}
}
if ((strArr.Length) < 2)
{
return null;
}
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,strArr[1]);
if (!path.Contains(".dll"))
{
path = path + ".dll";
}
Assembly assembly = Assembly.LoadFile(path);
object obj = assembly.CreateInstance(strArr[0], false);
if (log != null)
{
log("解析处理对象:" + reflectStr + "成功");
}
return obj;
}
catch (Exception ex)
{
if (log != null)
{
log("解析处理对象出错:" + ex.Message);
}
return null;
}
}
public void StartSwitch()
{
if (inList != null && inList.Count > 0)
{
foreach (IMessageSwitch s in inList)
{
if (log != null)
{
log("开启输输入端:" + s.GetTypeName());
}
s.Start();
}
}
if (outList != null && outList.Count > 0)
{
foreach (IMessageSwitch s in outList)
{
if (log != null)
{
log("开启输出端:" + s.GetTypeName());
}
s.Start();
}
}
}
public void StopSwitch()
{
if (inList != null && inList.Count > 0)
{
foreach (IMessageSwitch s in inList)
{
if (log != null)
{
log("停止输输入端:" + s.GetTypeName());
}
s.Stop();
}
}
if (outList != null && outList.Count > 0)
{
foreach (IMessageSwitch s in outList)
{
if (log != null)
{
log("停止输出端:" + s.GetTypeName());
}
s.Stop();
}
}
}
}
public class ConfDto
{
public string ReflectStr
{
get;
set;
}
public SwitchType Type
{
get;
set;
}
public string ConfStr
{
get;
set;
}
}
}
主转换器用户控件,主转换器界面实现
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MessageSwitch
{
public partial class SwitchMainUI : UserControl
{
private SwitchMian switchMian =null;
private int InTop = 0;
private int OutTop = 0;
public SwitchMainUI()
{
InitializeComponent();
}
private void btnAddIn_Click(object sender, EventArgs e)
{
object reflectObj = cmbType.SelectedValue;
if (reflectObj == null)
{
MessageBox.Show("请选择要添加的类型!", "提示");
return;
}
object swiObj = switchMian.GetObjectByReflectStr(reflectObj.ToString());
IMessageSwitch swi = swiObj as IMessageSwitch;
UserControl swiu = swiObj as UserControl;
swiu.Top = InTop;
InTop += swiu.Height+10;
tabPageIn.Controls.Add(swiu);
switchMian.AddToIn(swi);
}
private void btnAddOut_Click(object sender, EventArgs e)
{
object reflectObj = cmbType.SelectedValue;
if (reflectObj == null)
{
MessageBox.Show("请选择要添加的类型!", "提示");
return;
}
object swiObj = switchMian.GetObjectByReflectStr(reflectObj.ToString());
IMessageSwitch swi = swiObj as IMessageSwitch;
UserControl swiu = swiObj as UserControl;
swiu.Top = OutTop;
OutTop += swiu.Height+10;
tabPageOut.Controls.Add(swiu);
switchMian.AddToOut(swi);
}
private void btnSaveConfig_Click(object sender, EventArgs e)
{
string confStr=switchMian.GetConfig();
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SwitchMian.conf");
Util.WriteTxt(path, confStr);
MessageBox.Show("配置保存在SwitchMian.conf!", "提示");
}
private void btnStart_Click(object sender, EventArgs e)
{
switchMian.StartSwitch();
}
private void btnStop_Click(object sender, EventArgs e)
{
switchMian.StopSwitch();
}
private void SwitchMainUI_Load(object sender, EventArgs e)
{
switchMian = new SwitchMian(new WriteLog(WritLogs));
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SwitchType.conf");
string TypeConfStr = Util.ReadTxt(path);
if (TypeConfStr != "")
{
TypeConfStr = TypeConfStr.Replace("\r\n",(char)0+"");
string[] arr = TypeConfStr.Split((char)0);
List<CmbDto> cmbList = new List<CmbDto>();
foreach(string s in arr)
{
if (s == "")
{
continue;
}
string[] arrOne = s.Split('^');
if (arrOne.Length != 2)
{
MessageBox.Show("配置格式不对!格式:名称^反射串", "提示");
}
else
{
CmbDto dto = new CmbDto();
dto.Name = arrOne[0];
dto.ReflectStr = arrOne[1];
cmbList.Add(dto);
}
}
cmbType.DataSource = cmbList;
cmbType.ValueMember = "ReflectStr";
cmbType.DisplayMember = "Name";
}
string pathConf = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SwitchMian.conf");
if(System.IO.File.Exists(pathConf))
{
string conf=Util.ReadTxt(pathConf);
switchMian.LoadConfig(conf, new AddMessageSwitch(AddMessageSwitchDo));
switchMian.StartSwitch();
}
}
public void AddMessageSwitchDo(IMessageSwitch sw,SwitchType type)
{
UserControl swiu = sw as UserControl;
if (type == SwitchType.In)
{
swiu.Top = InTop;
InTop += swiu.Height + 10;
tabPageIn.Controls.Add(swiu);
}
if (type == SwitchType.Out)
{
swiu.Top = OutTop;
OutTop += swiu.Height + 10;
tabPageOut.Controls.Add(swiu);
}
}
private void WritLogs(string log)
{
object [] para=new object[1];
para[0]=log;
this.Invoke(new WriteLog(WritLogsDo), para);
}
private void WritLogsDo(string log)
{
txtInfo.Text += DateTime.Now.ToString("HH:mm:ss ")+ log + "\n";
}
class CmbDto
{
public string Name
{
get;
set;
}
public string ReflectStr
{
get;
set;
}
}
}
}
串口实现示例,对接串口消息
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace MessageSwitch
{
public partial class UCSerialPort : UserControl, IMessageSwitch
{
private SerialPort comm = new SerialPort();
private PushMessageToSwitch pushToSwitch;
SwitchType type;
private WriteLog log;
public UCSerialPort()
{
InitializeComponent();
}
public string GetTypeName()
{
return "串口";
}
public string GetConfig()
{
string confStr = cmbPortName.Text + "#" + cmbBaudrate.Text + "#" + cmbDataBits.Text + "#" + cmbStopBits.Text + "#" + cmbParity.Text;
return confStr;
}
public bool SetConfig(string confStr)
{
string[] arr = confStr.Split('#');
if (arr.Length != 5)
{
MessageBox.Show("串口配置格式不对!应该是#分隔的5位", "提示");
return false;
}
cmbPortName.Text = arr[0];
cmbBaudrate.Text = arr[1];
cmbDataBits.Text = arr[2];
cmbStopBits.Text = arr[3];
cmbParity.Text = arr[4];
return true;
}
public bool SetPushDelegate(PushMessageToSwitch push, SwitchType ptype, WriteLog plog)
{
pushToSwitch = push;
type = ptype;
log = plog;
return true;
}
public bool Start()
{
if (comm.IsOpen)
{
comm.Close();
}
comm.PortName = cmbPortName.Text;
comm.BaudRate = int.Parse(cmbBaudrate.Text);
comm.DataBits = int.Parse(cmbDataBits.Text);
switch (cmbStopBits.Text)
{
default:
comm.StopBits = StopBits.None;
break;
case "1":
comm.StopBits = StopBits.One;
break;
case "2":
comm.StopBits = StopBits.Two;
break;
case "1.5":
comm.StopBits = StopBits.OnePointFive;
break;
}
switch (cmbParity.Text)
{
default:
comm.Parity = Parity.None;
break;
case "Odd":
comm.Parity = Parity.Odd;
break;
case "Even":
comm.Parity = Parity.Even;
break;
case "Mark":
comm.Parity = Parity.Mark;
break;
case "Space":
comm.Parity = Parity.Space;
break;
}
try
{
comm.Open();
if (log != null)
{
log("启动:启动串口成功");
statePortName.ForeColor = Color.Blue;
}
}
catch (Exception ex)
{
statePortName.ForeColor = Color.Red;
comm = new SerialPort();
comm.NewLine = "\r\n";
comm.RtsEnable = true;
comm.DataReceived += cmb_DataReceived;
MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
return false;
}
return true;
}
public bool Stop()
{
if (comm.IsOpen)
{
comm.Close();
statePortName.ForeColor = Color.Red;
if (log != null)
{
log("停止:串口已关闭");
statePortName.ForeColor = Color.Blue;
}
}
return true;
}
public bool SendMessage(byte[] msgByteArr)
{
if (comm.IsOpen)
{
comm.Write(msgByteArr, 0, msgByteArr.Count());
}
else
{
if (log != null)
{
log("串口未打开,无法发送");
statePortName.ForeColor = Color.Blue;
}
}
return true;
}
public string GetReflectStr()
{
return "MessageSwitch.UCSerialPort,MessageSwitch.dll";
}
private void UCSerialPort_Load(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
if (ports == null || ports.Count() == 0)
{
MessageBox.Show("检测到当前运行电脑没有串口!");
}
Array.Sort(ports);
cmbPortName.Items.AddRange(ports);
string[] baudrates = { "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200" };
cmbBaudrate.Items.AddRange(baudrates);
string[] databits = { "8", "7", "6", "5", "4" };
cmbDataBits.Items.AddRange(databits);
string[] stopbits = { "1", "1.5", "2" };
cmbStopBits.Items.AddRange(stopbits);
string[] parity = { "None", "Odd", "Even", "Mark", "Speace" };
cmbParity.Items.AddRange(parity);
cmbPortName.SelectedIndex = cmbPortName.Items.Count > 0 ? 0 : -1;
cmbBaudrate.SelectedIndex = cmbBaudrate.Items.IndexOf("9600");
cmbDataBits.SelectedIndex = cmbDataBits.Items.IndexOf("8");
cmbStopBits.SelectedIndex = cmbStopBits.Items.IndexOf("1");
cmbParity.SelectedIndex = cmbParity.Items.IndexOf("None");
cmbPortName.DropDownStyle = ComboBoxStyle.DropDownList;
cmbBaudrate.DropDownStyle = ComboBoxStyle.DropDownList;
cmbDataBits.DropDownStyle = ComboBoxStyle.DropDownList;
cmbStopBits.DropDownStyle = ComboBoxStyle.DropDownList;
cmbParity.DropDownStyle = ComboBoxStyle.DropDownList;
comm.NewLine = "\r\n";
comm.RtsEnable = true;
comm.DataReceived += cmb_DataReceived;
}
void cmb_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = comm.BytesToRead;
byte[] buf = new byte[n];
comm.Read(buf, 0, n);
string lineStr = System.Text.Encoding.Default.GetString(buf);
lineStr = Util.DealNotSeeToSeeChar(lineStr);
if (pushToSwitch != null)
{
pushToSwitch(buf, type);
}
}
private void btnStart_Click(object sender, EventArgs e)
{
Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
Stop();
}
}
}
TCP服务端实现示例,实现TCP服务端接收客户端消息
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace MessageSwitch
{
public partial class UCTcpServer : UserControl, IMessageSwitch
{
private Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private bool IsOpen = false;
private PushMessageToSwitch pushToSwitch;
SwitchType type;
private WriteLog log;
public Socket mianClient = null;
public UCTcpServer()
{
InitializeComponent();
}
public string GetTypeName()
{
return "TCP服务端";
}
public string GetConfig()
{
string confStr = txtIp.Text + "#" + txtPort.Text;
return confStr;
}
public bool SetConfig(string confStr)
{
string[] arr = confStr.Split('#');
if (arr.Length != 2)
{
MessageBox.Show("TCP配置格式不对!应该是#分隔的2位", "提示");
return false;
}
txtIp.Text = arr[0];
txtPort.Text = arr[1];
return true;
}
public bool SetPushDelegate(PushMessageToSwitch push, SwitchType ptype, WriteLog plog)
{
pushToSwitch = push;
type = ptype;
log = plog;
return true;
}
public bool Start()
{
if (txtPort.Text == "")
{
if (log != null)
{
log("启动:没有设置端口号");
}
return false;
}
if (txtIp.Text == "")
{
if (log != null)
{
log("启动:没有设置端IP");
}
return false;
}
if (socket != null)
{
socket.Close();
socket.Dispose();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IsOpen = false;
}
IPAddress hostIP = IPAddress.Any;
IPAddress.TryParse(txtIp.Text, out hostIP);
if (Util.PortInUse(Convert.ToInt32(txtPort.Text)))
{
if (log != null)
{
log("启动TCP服务:当前电脑端口:" + txtPort.Text + "已经被占用");
}
MessageBox.Show("当前电脑端口:" + txtPort.Text + "已经被占用", "提示", MessageBoxButtons.OK);
return false;
}
IPEndPoint ep = new IPEndPoint(hostIP, Convert.ToInt32(txtPort.Text));
socket.Bind(ep);
try
{
socket.Listen(20);
if (log != null)
{
log("启动TCP服务:启动TCP服务成功");
}
stateIp.ForeColor = Color.Blue;
Thread tcpThread = new Thread(new ThreadStart(TcpListenClientConnect));
IsOpen = true;
tcpThread.Start();
return true;
}
catch (Exception ex)
{
IsOpen = false;
MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
return false;
}
}
public bool Stop()
{
if (socket != null)
{
socket.Close();
stateIp.ForeColor = Color.Red;
socket.Dispose();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IsOpen = false;
if (log != null)
{
log("停止TCP服务:TCP已释放");
}
}
return true;
}
public bool SendMessage(byte[] msgByteArr)
{
if (mianClient != null)
{
mianClient.Send(msgByteArr);
return true;
}
else
{
if (log != null)
{
log("TCP无连接客户端,无法发送,确认防火墙关闭!");
}
return false;
}
}
public string GetReflectStr()
{
return "MessageSwitch.UCTcpServer,MessageSwitch.dll";
}
private void UCTcpServer_Load(object sender, EventArgs e)
{
txtIp.Text = Util.GetIpv4Str();
}
private void TcpListenClientConnect()
{
while (true)
{
try
{
if (IsOpen == false)
{
break;
}
Socket oneClient = socket.Accept();
string clentIP = ((IPEndPoint)oneClient.RemoteEndPoint).Address.ToString();
string clientPort = ((IPEndPoint)oneClient.RemoteEndPoint).Port.ToString();
if (log != null)
{
log("客户端:" + clentIP + ":" + clientPort + "连接了本服务");
}
if (mianClient == null)
{
if (log != null)
{
log("客户端:" + clentIP + ":" + clientPort + "作为主客户端");
}
mianClient = oneClient;
Thread newThread = new Thread(ListenClientData);
newThread.Start();
}
else
{
if (log != null)
{
log("已有客户端连接本服务,将断开当前客户端请求");
}
byte[] byteArray = System.Text.Encoding.Default.GetBytes("已有连接连上该端口了!");
oneClient.Send(byteArray);
oneClient.Close();
}
}
catch (Exception ex)
{
if (log != null)
{
log("服务端侦听异常:" + ex.Message);
}
}
}
}
public void ListenClientData()
{
byte[] bytes = new byte[83886080];
int datai = -1;
try
{
while (true)
{
if (IsOpen == false)
{
break;
}
datai = mianClient.Receive(bytes);
if (datai > 0)
{
if (pushToSwitch != null)
{
byte[] buf = new byte[datai];
Array.Copy(bytes, buf, datai);
pushToSwitch(buf, type);
}
}
}
}
catch (System.Exception ex)
{
if (log != null)
{
log("侦听客户端消息异常:" + ex.Message);
}
}
finally
{
if (mianClient != null)
{
mianClient.Close();
mianClient.Dispose();
mianClient = null;
}
}
}
private void btnStart_Click(object sender, EventArgs e)
{
Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
Stop();
}
}
}
工具类,共用方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Net.NetworkInformation;
using System.Net;
namespace MessageSwitch
{
public class Util
{
public static T ReadLocalData<T>(string path)
{
if (File.Exists(path))
{
try
{
string str = ReadTxt(path);
byte[] arr = Convert.FromBase64String(str);
str = System.Text.Encoding.Default.GetString(arr);
return XmlDeserialize<T>(str, Encoding.UTF8);
}
catch (Exception e)
{
throw e;
}
}
else
{
return default(T);
}
}
public static bool WriteLocalData(object data, string path)
{
if (File.Exists(path))
{
File.Delete(path);
try
{
string str = Serializer(data.GetType(), data);
byte[] arr = System.Text.Encoding.Default.GetBytes(str);
str = Convert.ToBase64String(arr);
WriteTxt(path, str);
return true;
}
catch (Exception e)
{
throw e;
}
}
else
{
try
{
string str = Serializer(data.GetType(), data);
byte[] arr = System.Text.Encoding.Default.GetBytes(str);
str = Convert.ToBase64String(arr);
WriteTxt(path, str);
return true;
}
catch (Exception e)
{
throw e;
}
}
}
public static bool DeleteLocalData(string id, string pat)
{
string path = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), id + ".aup");
if (pat != null && pat != string.Empty)
{
path = Path.Combine(pat, id + ".aup");
}
if (File.Exists(path))
{
File.Delete(path);
}
return true;
}
public static string Serializer(Type type, object obj)
{
MemoryStream Stream = new MemoryStream();
XmlSerializer xml = new XmlSerializer(type);
try
{
xml.Serialize(Stream, obj);
}
catch (InvalidOperationException)
{
throw;
}
Stream.Position = 0;
StreamReader sr = new StreamReader(Stream);
string str = sr.ReadToEnd();
sr.Dispose();
Stream.Dispose();
return str;
}
public static T XmlDeserialize<T>(string s, Encoding encoding)
{
try
{
if (string.IsNullOrEmpty(s))
{
throw new ArgumentNullException("s");
}
if (encoding == null)
{
throw new ArgumentNullException("encoding");
}
XmlSerializer mySerializer = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(encoding.GetBytes(s)))
{
using (StreamReader sr = new StreamReader(ms, encoding))
{
return (T)mySerializer.Deserialize(sr);
}
}
}
catch (Exception ex)
{
return default(T);
}
}
public static string ReadTxt(string path)
{
FileStream fs = null;
try
{
fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader sr = new StreamReader(fs);
string str = sr.ReadToEnd();
return str;
}
finally
{
if (fs != null)
{
fs.Close();
}
}
}
public static bool WriteTxt(string path, string str)
{
FileStream fs = null;
StreamWriter sw1 = null;
try
{
if (File.Exists(path))
{
File.Delete(path);
}
fs = new FileStream(path, FileMode.CreateNew);
sw1 = new StreamWriter(fs);
sw1.Write(str);
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (sw1 != null)
{
sw1.Close();
}
if (fs != null)
{
fs.Close();
}
}
}
public static string DealNotSeeToSeeChar(string data)
{
for (int i = 0; i <= 31; i++)
{
if (i == 6)
{
data = data.Replace((char)i + "", "[ACK]");
}
else if (i == 5)
{
data = data.Replace((char)i + "", "[ENQ]");
}
else if (i == 4)
{
data = data.Replace((char)i + "", "[EOT]");
}
else if (i == 3)
{
data = data.Replace((char)i + "", "[ETX]");
}
else if (i == 2)
{
data = data.Replace((char)i + "", "[STX]");
}
else
{
data = data.Replace((char)i + "", "[" + i + "]");
}
}
data.Replace((char)127 + "", "[127]");
return data;
}
public static bool PortInUse(int port)
{
bool inUse = false;
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach (IPEndPoint endPoint in ipEndPoints)
{
if (endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
public static string GetIpv4Str()
{
System.Net.IPAddress[] arrIPAddresses = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName());
foreach (System.Net.IPAddress ip in arrIPAddresses)
{
if (ip.AddressFamily.Equals(System.Net.Sockets.AddressFamily.InterNetwork))
{
return ip.ToString();
}
}
return string.Empty;
}
}
}
运行效果-串口转串口和TCP服务
这样就可以任意组合转换器两端的协议了。可以串口转串口,串口转tcp,tcp转tcp,tcp转tdp,串口转udp====。而且每端可以配置多种协议。所以把这个称为超级转换器。分为转换中心和转换实现。
善于抽取共性,就能大大降低复杂度,实现灵活又强大的功能,面向接口编程的好处。
|