大家好,我是青空。
由于现在工作上,有很多socket交互的情况,自己在网上找了一些工具, 但是要么不好用,要么就是只能使用几天,就需要收费了。 青空就想着自己搞一个好了, 针对自己的应用场景,直接定制。
那就先上个图吧
已实现的功能
目前已经完成了第一个版本。功能点如下:
根据TCP/IP 协议链接到服务端通过 ASCII、Hex 两种编码格式进行消息互通格式化显示消息发送、接收数据自动重发命令记录命令发送历史核心代码
在这个工具中,最核心的不过是在于,建立socket链接,然后进行消息的接收和发送。
建立socket的过程,先确定 TCP 服务端IP和端口是否准确,然后再通过 socket api 进行连接。建立连接之后,进行状态的改变,启动接收消息的线程。
var ipString = cbServerIp.Text.ToString().Trim();var ipPort = cbServerPort.Text.ToString().Trim();if (string.IsNullOrWhiteSpace(ipString) || string.IsNullOrWhiteSpace(ipPort)){ MessageBox.Show("请先输入服务器IP和端口号"); return;}if (Connected == false){ socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IP = IPAddress.Parse(ipString); port = Convert.ToInt32(ipPort); remoteEndPoint = new IPEndPoint(IP, port); try { socket.Connect(remoteEndPoint); Connected = true; btnConnect.Text = "断开服务器"; connectStatus.Text = "This socket is connected"; connectStatus.ForeColor = Color.Green; } catch (SocketException ex) { Connected = false; btnConnect.Text = "连接服务器"; connectStatus.Text = "This socket is not connected"; connectStatus.ForeColor = Color.Red; } Thread thread = new Thread(ReceiveMsg); thread.IsBackground = true; thread.Start();}else{ Connected = false; btnConnect.Text = "连接服务器"; socket.Disconnect(false); socket.Close(); connectStatus.Text = "This socket is not connected"; connectStatus.ForeColor = Color.Red;}
接下来就介绍一下,我们是如何接收消息的,接收消息的过程我们是在循环遍历读取 socket 连接中的消息,然后展示到我们的接收区的文本框中。
while (Connected){ StringBuilder sb = new StringBuilder("[接收] "); if (closeForm == false) { try { if (Connected == false) { return; } byte[] data = new byte[1024]; var n = socket.Receive(data); if (n > 0) { byte[] buf = new byte[n]; Array.Copy(data, 0, buf, 0, n); if (chbShowTime.Checked) { sb.Append("["); var now = DateTime.Now; sb.Append(now.ToString("yyyy-MM-dd")); sb.Append(" "); sb.Append(now.ToString("HH:mm:ss:fff")); sb.Append("] "); } if (rdbRevASCII.Checked) { sb.Append(Encoding.ASCII.GetString(buf)); } if (rdbRevHex.Checked) { foreach (var b in buf) { sb.Append(b.ToString("X2") + " "); } } if (chbNewLine.Checked) { sb.Append("\n"); } } } catch (SocketException ex) { Connected = false; btnConnect.Text = "连接服务器"; MessageBox.Show("与服务器断开 " + ex.Message, "错误提示"); } catch (Exception ex) { Connected = false; btnConnect.Text = "连接服务器"; showMsg("接收数据异常,可能已经断联"); } } showMsg(sb.ToString());}
通常我们会把UI线程和业务线程给分离开,这是由于如果不进行分离的话,如果业务线程卡住的话, UI线程会出现未响应的状态。那我们为了能够在UI线程显示数据,我们就需要通过委托调用的方式能够让UI进行正常运行, 代码如下。
if (this.InvokeRequired){ ReceiveMsgDele receiveMsgDele = new ReceiveMsgDele(showMsg); rtbRevText.Invoke(receiveMsgDele, new object[] { msg });}else{ rtbRevText.AppendText(msg);}
下一步
在目前的功能基础上,增加定制化的功能, 比如持久化消息的发送历史,批量发送命令,有交互性的重复发送命令等。
总结
今天青空给大家介绍了最近自己开发的 TCP/IP 的调试工具,实现了互通消息的功能, 更多其他的功能在持续开发中,对这个感兴趣的话,可以联系我。暂时不对齐进行开源,等到代码完善了之后再考虑开源的事项。