C# 的TCPClient异步连接与异步读数据
2016-05-15 22:09
405 查看
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using System.Threading; namespace TcpClientTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } TcpClient tcp = null; NetworkStream workStream = null; private enum DataMode { Text, Hex } private char[] HexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a','b', 'c', 'd', 'e', 'f' }; private bool CharInArray(char aChar, char[] charArray) { return (Array.Exists<char>(charArray, delegate(char a) { return a == aChar; })); } ///
/// 十六进制字符串转换字节数组 ///
/// /// private byte[] HexStringToByteArray(string s) { // s = s.Replace(" ", ""); StringBuilder sb = new StringBuilder(s.Length); foreach (char aChar in s) { if (CharInArray(aChar, HexDigits)) sb.Append(aChar); } s = sb.ToString(); int bufferlength; if ((s.Length % 2) == 1) bufferlength = s.Length / 2 + 1; else bufferlength = s.Length / 2; byte[] buffer = new byte[bufferlength]; for (int i = 0; i < bufferlength - 1; i++) buffer[i] = (byte)Convert.ToByte(s.Substring(2 * i, 2), 16); if (bufferlength > 0) buffer[bufferlength - 1] = (byte)Convert.ToByte(s.Substring(2 * (bufferlength - 1), (s.Length % 2 == 1 ? 1 :2)), 16); return buffer; } /// /// 字节数组转换十六进制字符串 /// /// /// private string ByteArrayToHexString(byte[] data) { StringBuilder sb = new StringBuilder(data.Length * 3); foreach (byte b in data) sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' ')); return sb.ToString().ToUpper(); } /// /// 当前接收模式 /// private DataMode CurrentReceiveDataMode { get { return (chkHexReceive.Checked) ? DataMode.Hex : DataMode.Text; } set { chkHexReceive.Checked = (value == DataMode.Text); } } /// /// 当前发送模式 /// private DataMode CurrentSendDataMode { get { return (chkHexSend.Checked) ? DataMode.Hex : DataMode.Text; } set { chkHexSend.Checked = (value == DataMode.Text); } } /// /// 发送数据 /// private void SendData() { if (workStream != null) { byte[] data; if (CurrentSendDataMode == DataMode.Text) { data = Encoding.ASCII.GetBytes(rtfSend.Text); } else { // 转换用户十六进制数据到字节数组 data = HexStringToByteArray(rtfSend.Text); } workStream.Write(data,0,data.Length); } } delegate void SetTextCallback(string text); delegate void SetControl(); delegate void GetData(byte[] data); /// /// 异步接收数据 /// /// private void OnGetData(byte[] data) { string sdata; if (CurrentReceiveDataMode == DataMode.Text) { sdata = new string(Encoding.UTF8.GetChars(data)); } else { sdata = ByteArrayToHexString(data); } rtfReceive.Invoke(new EventHandler(delegate { rtfReceive.AppendText(sdata); })); } /// /// 异步设置Log /// /// private void SetText(string text) { if (rtfLog.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { rtfLog.AppendText(text + Environment.NewLine); } } public ManualResetEvent connectDone = new ManualResetEvent(false); /// /// 异步连接的回调函数 /// /// private void ConnectCallback(IAsyncResult ar) { connectDone.Set(); TcpClient t = (TcpClient)ar.AsyncState; try { if (t.Connected) { SetText("连接成功"); t.EndConnect(ar); SetText("连接线程完成"); } else { SetText("连接失败"); t.EndConnect(ar); } } catch (SocketException se) { SetText("连接发生错误ConnCallBack.......:"+se.Message); } } /// /// 异步连接 /// private void Connect() { if ((tcp == null) || (!tcp.Connected)) { try { tcp = new TcpClient(); tcp.ReceiveTimeout = 10; connectDone.Reset(); SetText("Establishing Connection to " + txtIP.Text); tcp.BeginConnect(txtIP.Text, (int) numPort.Value, new AsyncCallback(ConnectCallback), tcp); connectDone.WaitOne(); if ((tcp != null) && (tcp.Connected)) { workStream = tcp.GetStream(); SetText("Connection established"); asyncread(tcp); } } catch (Exception se) { rtfLog.AppendText(se.Message+" Conn......."+Environment.NewLine); } } } /// /// 断开连接 /// private void DisConnect() { if ((tcp != null) && (tcp.Connected)) { workStream.Close(); tcp.Close(); } } /// /// 设置控件状态 /// private void setBtnStatus() { if ((btnConnect.InvokeRequired) || (btnSend.InvokeRequired)) { this.Invoke(new SetControl(setBtnStatus)); } else { int con = ((tcp == null) || (!tcp.Connected)) ? 0 : 1; string[] constr = { "连接", "断开" }; bool[] btnEnabled = { false, true }; btnConnect.Text = constr[con]; btnSend.Enabled = btnEnabled[con]; } } /// /// 连接按钮 /// /// /// private void btnConnect_Click(object sender, EventArgs e) { if ((tcp != null) && (tcp.Connected)) { DisConnect(); } else { Connect(); } setBtnStatus(); } /// /// 发送数据按钮 /// /// /// private void btnSend_Click(object sender, EventArgs e) { try { SendData(); } catch (Exception se) { rtfLog.AppendText(se.Message+Environment.NewLine); } } /// /// 异步读TCP数据 /// /// private void asyncread(TcpClient sock) { StateObject state = new StateObject(); state.client = sock; NetworkStream stream = sock.GetStream(); if (stream.CanRead) { try { IAsyncResult ar = stream.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(TCPReadCallBack), state); } catch (Exception e) { SetText("Network IO problem " + e.ToString()); } } } /// /// TCP读数据的回调函数 /// /// private void TCPReadCallBack(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState; //主动断开时 if ((state.client == null) || (!state.client.Connected)) return; int numberOfBytesRead; NetworkStream mas = state.client.GetStream(); string type = null; numberOfBytesRead = mas.EndRead(ar); state.totalBytesRead += numberOfBytesRead; SetText("Bytes read ------ "+ numberOfBytesRead.ToString()); if (numberOfBytesRead > 0) { byte[] dd = new byte[numberOfBytesRead]; Array.Copy(state.buffer,0,dd,0,numberOfBytesRead); OnGetData(dd); mas.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(TCPReadCallBack), state); } else { //被动断开时 mas.Close(); state.client.Close(); SetText("Bytes read ------ "+ numberOfBytesRead.ToString()); SetText("不读了"); mas = null; state = null; setBtnStatus(); } } } internal class StateObject { public TcpClient client = null; public int totalBytesRead = 0; public const int BufferSize = 1024; public string readType = null; public byte[] buffer = new byte[BufferSize]; public StringBuilder messageBuffer = new StringBuilder(); } }
相关文章推荐
- Fidder 网络抓包调试工具
- 【网络】ARP协议
- 网络编程即Socket编程(一)
- HttpURLConnection编写方法
- TCP/IP总结
- HttpClient的post请求
- Java网络通信编程经验之谈
- 网络攻防研究第001篇:尝试暴力破解某高校研究生管理系统学生密码
- http://blog.sina.com.cn/rss/2790628754.xml
- http://www.cnblogs.com/shortboy/p/4429368.html
- Http百度请求数据
- 运维网络基础
- 华中农业大学第四届程序设计大赛网络同步赛 F
- 获取网络图片+ViewPager+自动轮播
- HttpClient请求数据
- Deep Learning学习 之 卷积神经网络(文字识别系统LeNet-5)
- 20159217《网络攻防实践》第十一周学习总结
- 网络获取Json文件解析范例
- 周赛题 (华中农业大学第四届程序设计大赛网络同步赛)
- 神经网络中前向传播和反向传播解析