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; }));
}
/// <summary>
/// 十六进制字符串转换字节数组
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 字节数组转换十六进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 当前接收模式
/// </summary>
private DataMode CurrentReceiveDataMode
{
get
{
return (chkHexReceive.Checked) ? DataMode.Hex : DataMode.Text;
}
set
{
chkHexReceive.Checked = (value == DataMode.Text);
}
}
/// <summary>
/// 当前发送模式
/// </summary>
private DataMode CurrentSendDataMode
{
get
{
return (chkHexSend.Checked) ? DataMode.Hex : DataMode.Text;
}
set
{
chkHexSend.Checked = (value == DataMode.Text);
}
}
/// <summary>
/// 发送数据
/// </summary>
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);
/// <summary>
/// 异步接收数据
/// </summary>
/// <param name="data"></param>
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);
}));
}
/// <summary>
/// 异步设置Log
/// </summary>
/// <param name="text"></param>
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);
/// <summary>
/// 异步连接的回调函数
/// </summary>
/// <param name="ar"></param>
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);
}
}
/// <summary>
/// 异步连接
/// </summary>
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);
}
}
}
/// <summary>
/// 断开连接
/// </summary>
private void DisConnect()
{
if ((tcp != null) && (tcp.Connected))
{
workStream.Close();
tcp.Close();
}
}
/// <summary>
/// 设置控件状态
/// </summary>
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];
}
}
/// <summary>
/// 连接按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnConnect_Click(object sender, EventArgs e)
{
if ((tcp != null) && (tcp.Connected))
{
DisConnect();
}
else
{
Connect();
}
setBtnStatus();
}
/// <summary>
/// 发送数据按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
try
{
SendData();
}
catch (Exception se)
{
rtfLog.AppendText(se.Message+Environment.NewLine);
}
}
/// <summary>
/// 异步读TCP数据
/// </summary>
/// <param name="sock"></param>
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());
}
}
}
/// <summary>
/// TCP读数据的回调函数
/// </summary>
/// <param name="ar"></param>
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();
}
}
Form1.Design.cs
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.txtIP = new System.Windows.Forms.TextBox();
this.numPort = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.btnConnect = new System.Windows.Forms.Button();
this.chkHexReceive = new System.Windows.Forms.CheckBox();
this.chkHexSend = new System.Windows.Forms.CheckBox();
this.rtfSend = new System.Windows.Forms.RichTextBox();
this.rtfReceive = new System.Windows.Forms.RichTextBox();
this.btnSend = new System.Windows.Forms.Button();
this.rtfLog = new System.Windows.Forms.RichTextBox();
((System.ComponentModel.ISupportInitialize)(this.numPort)).BeginInit();
this.SuspendLayout();
//
// txtIP
//
this.txtIP.Location = new System.Drawing.Point(58, 12);
this.txtIP.Name = "txtIP";
this.txtIP.Size = new System.Drawing.Size(142, 21);
this.txtIP.TabIndex = 0;
this.txtIP.Text = "127.0.0.1";
//
// numPort
//
this.numPort.Location = new System.Drawing.Point(58, 39);
this.numPort.Maximum = new decimal(new int[] {
65535,
0,
0,
0});
this.numPort.Name = "numPort";
this.numPort.Size = new System.Drawing.Size(142, 21);
this.numPort.TabIndex = 1;
this.numPort.Value = new decimal(new int[] {
9099,
0,
0,
0});
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(11, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(17, 12);
this.label1.TabIndex = 2;
this.label1.Text = "IP";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(11, 43);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 12);
this.label2.TabIndex = 3;
this.label2.Text = "Port";
//
// btnConnect
//
this.btnConnect.Location = new System.Drawing.Point(14, 66);
this.btnConnect.Name = "btnConnect";
this.btnConnect.Size = new System.Drawing.Size(75, 23);
this.btnConnect.TabIndex = 4;
this.btnConnect.Text = "连接";
this.btnConnect.UseVisualStyleBackColor = true;
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
//
// chkHexReceive
//
this.chkHexReceive.AutoSize = true;
this.chkHexReceive.Location = new System.Drawing.Point(14, 100);
this.chkHexReceive.Name = "chkHexReceive";
this.chkHexReceive.Size = new System.Drawing.Size(96, 16);
this.chkHexReceive.TabIndex = 5;
this.chkHexReceive.Text = "十六进制接收";
this.chkHexReceive.UseVisualStyleBackColor = true;
//
// chkHexSend
//
this.chkHexSend.AutoSize = true;
this.chkHexSend.Location = new System.Drawing.Point(109, 100);
this.chkHexSend.Name = "chkHexSend";
this.chkHexSend.Size = new System.Drawing.Size(96, 16);
this.chkHexSend.TabIndex = 6;
this.chkHexSend.Text = "十六进制发送";
this.chkHexSend.UseVisualStyleBackColor = true;
//
// rtfSend
//
this.rtfSend.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.rtfSend.Location = new System.Drawing.Point(211, 12);
this.rtfSend.Name = "rtfSend";
this.rtfSend.Size = new System.Drawing.Size(453, 96);
this.rtfSend.TabIndex = 7;
this.rtfSend.Text = "";
//
// rtfReceive
//
this.rtfReceive.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.rtfReceive.Location = new System.Drawing.Point(211, 122);
this.rtfReceive.Name = "rtfReceive";
this.rtfReceive.Size = new System.Drawing.Size(453, 327);
this.rtfReceive.TabIndex = 8;
this.rtfReceive.Text = "";
//
// btnSend
//
this.btnSend.Enabled = false;
this.btnSend.Location = new System.Drawing.Point(130, 66);
this.btnSend.Name = "btnSend";
this.btnSend.Size = new System.Drawing.Size(75, 23);
this.btnSend.TabIndex = 9;
this.btnSend.Text = "发送";
this.btnSend.UseVisualStyleBackColor = true;
this.btnSend.Click += new System.EventHandler(this.btnSend_Click);
//
// rtfLog
//
this.rtfLog.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.rtfLog.Location = new System.Drawing.Point(12, 122);
this.rtfLog.Name = "rtfLog";
this.rtfLog.Size = new System.Drawing.Size(193, 327);
this.rtfLog.TabIndex = 10;
this.rtfLog.Text = "";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(676, 461);
this.Controls.Add(this.rtfLog);
this.Controls.Add(this.btnSend);
this.Controls.Add(this.rtfReceive);
this.Controls.Add(this.rtfSend);
this.Controls.Add(this.chkHexSend);
this.Controls.Add(this.chkHexReceive);
this.Controls.Add(this.btnConnect);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.numPort);
this.Controls.Add(this.txtIP);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.numPort)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox txtIP;
private System.Windows.Forms.NumericUpDown numPort;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.CheckBox chkHexReceive;
private System.Windows.Forms.CheckBox chkHexSend;
private System.Windows.Forms.RichTextBox rtfSend;
private System.Windows.Forms.RichTextBox rtfReceive;
private System.Windows.Forms.Button btnSend;
private System.Windows.Forms.RichTextBox rtfLog;
}
}