您的位置:首页 > 理论基础 > 计算机网络

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();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: