编写TCP异步通信组件之AsyncTCPClient
来源:互联网 发布:centos yum pip 编辑:程序博客网 时间:2024/06/11 10:27
/*
*
* 作者:俞伟
* 时间:2007-11-29
* 作用:声明AsyncTCPClient类,TCP异步通信客户端
* 邮件:michelsn@163.com
*
* */
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace SocketLibrary {
public partial class AsyncTCPClient : Component {
#region 构造函数
public AsyncTCPClient() {
InitializeComponent();
}
public AsyncTCPClient(IContainer container) {
container.Add(this);
InitializeComponent();
}
#endregion
#region 变量
private Socket mSocket = null;
private string localIPAddress = "";
private int localPort = 0;
private string remoteIPAddress = "";
private int remotePort = 0;
private string keyID = "";
private bool IsExit = false;
private SocketObject so = new SocketObject();
#endregion
#region 变量属性
/// <summary>
/// Socket标志
/// </summary>
public string KeyID {
get {
return keyID;
}
}
/// <summary>
/// 本机地址
/// </summary>
public string LocalIPAddress {
get {
return localIPAddress;
}
}
/// <summary>
/// 本机端口
/// </summary>
public int LocalPort {
get {
return localPort;
}
}
/// <summary>
/// 主机地址
/// </summary>
public string RemoteIPAddress {
get {
return remoteIPAddress;
}
}
/// <summary>
/// 主机端口
/// </summary>
public int RemotePort {
get {
return remotePort;
}
}
/// <summary>
/// 消息的终止判断符
/// </summary>
public static string EndChar {
get {
return new string((char)0, 1);
}
}
#endregion
#region 代理委托
/// <summary>
/// Socket异常错误事件
/// </summary>
/// <param name="aKeyID">异常错误所有者的标志值</param>
/// <param name="aErrorMessage">异常错误信息</param>
public delegate void SocketErrorHandler(string aKeyID, string aErrorMessage);
/// <summary>
/// 接收二进制数据
/// </summary>
/// <param name="aData">接收到的数据</param>
public delegate void BinaryDataAvailableHandler(byte[] aData);
/// <summary>
/// 接收字符串数据
/// </summary>
/// <param name="aData">接收到的数据</param>
public delegate void StringDataAvailableHandler(string aData);
#endregion
#region 事件声明
public event SocketErrorHandler OnSocketError;
public event BinaryDataAvailableHandler OnBinaryDataAvailable;
public event StringDataAvailableHandler OnStringDataAvailable;
#endregion
#region 事件代理方法
/// <summary>
/// 显示异常错误信息
/// </summary>
/// <param name="aKeyID">异常错误所有者的标志值</param>
/// <param name="aErrorMessage">异常错误信息</param>
private void DisplayError(string aKeyID, string aErrorMessage) {
if (OnSocketError != null) {
OnSocketError(aKeyID, aErrorMessage);
}
}
/// <summary>
/// 接收二进制数据
/// </summary>
/// <param name="aData">接收到的数据</param>
private void BinaryDataAvailable(byte[] aData) {
if (OnBinaryDataAvailable != null) {
OnBinaryDataAvailable(aData);
}
}
/// <summary>
/// 接收字符串数据
/// </summary>
/// <param name="aData">接收到的数据</param>
private void StringDataAvailable(string aData) {
if (OnStringDataAvailable != null) {
OnStringDataAvailable(aData);
}
}
#endregion
#region 内部方法
/// <summary>
/// 异步接收数据
/// </summary>
/// <param name="ar">IAsyncResult接口对象</param>
private void AsyncDataReceive(IAsyncResult ar) {
SocketObject so = (SocketObject)ar.AsyncState;
try {
if (IsExit == false) {
int iReceiveCount = so.WorkSocket.EndReceive(ar);
if (iReceiveCount > 0) {
so.sbBuffer.Append(Encoding.UTF8.GetString(so.Buffer, 0, iReceiveCount));
string strReceive = so.sbBuffer.ToString();
if (strReceive.Substring(strReceive.Length - 1, 1) == EndChar) {
//本次接收
strReceive = strReceive.Remove(strReceive.Length - 1, 1);
//调用外部用户接口方法
BinaryDataAvailable(Encoding.UTF8.GetBytes(strReceive));
StringDataAvailable(strReceive);
//清空数据
so.sbBuffer.Remove(0, so.sbBuffer.Length);
}
if (IsExit == false) {
so.WorkSocket.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, new AsyncCallback(AsyncDataReceive), so);
}
} else {
Disconnect();
}
} else {
Disconnect();
}
} catch (Exception ex) {
DisplayError(KeyID, ex.Message);
}
}
/// <summary>
/// 异步发送消息
/// </summary>
/// <param name="ar">IAsyncResult接口对象</param>
private void AsyncSend(IAsyncResult ar) {
try {
int iSendCount = mSocket.EndSend(ar);
} catch (Exception ex) {
DisplayError(KeyID, ex.Message);
}
}
/// <summary>
/// 发送消息(异步发送)
/// </summary>
/// <param name="aData">要发送的消息</param>
private void Send(byte[] aData) {
try {
mSocket.BeginSend(aData, 0, aData.Length, SocketFlags.None, new AsyncCallback(AsyncSend), null);
} catch (Exception ex) {
DisplayError(KeyID, ex.Message);
}
}
private void AsyncConnect(IAsyncResult ar) {
Socket sock = (Socket)ar.AsyncState;
try {
sock.EndConnect(ar);
if (sock.Connected) {
//启动消息接收事件
so.KeyID = KeyID;
so.WorkSocket = sock;
if (IsExit == false) {
so.WorkSocket.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, new AsyncCallback(AsyncDataReceive), so);
}
} else {
new Exception("Unable to connect to remote machine, Connect Failed!");
}
} catch (Exception ex) {
DisplayError(KeyID, ex.Message);
}
}
#endregion
#region 对外开发的接口方法
/// <summary>
/// 初始化本机Socket通信机制
/// </summary>
/// <param name="aLocalIPAddress">本机地址</param>
/// <param name="aLocalPort">本机端口</param>
/// <returns>返回操作是否成功</returns>
public bool InitSocket(string aLocalIPAddress, int aLocalPort) {
bool bActive = false;
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LingerOption lo = new LingerOption(false, 10);
mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo);
try {
IPAddress ip = Dns.GetHostAddresses(aLocalIPAddress)[0];
if (aLocalPort == 0) {
Random rd = new Random(5000);
aLocalPort = rd.Next(30000);
}
localIPAddress = ip.ToString();
localPort = aLocalPort;
IPEndPoint ipe = new IPEndPoint(ip, aLocalPort);
keyID = Guid.NewGuid().ToString();
mSocket.Bind(ipe);
bActive = true;
} catch (Exception ex) {
bActive = false;
DisplayError(KeyID, ex.Message);
}
return bActive;
}
/// <summary>
/// 连接主机
/// </summary>
/// <param name="aRemoteIPAddress">主机地址</param>
/// <param name="aRemotePort">主机端口</param>
/// <returns>返回操作是否成功</returns>
public bool Connect(string aRemoteIPAddress, int aRemotePort) {
if (mSocket == null)
return false;
try {
remoteIPAddress = aRemoteIPAddress;
remotePort = aRemotePort;
mSocket.Blocking = false;
mSocket.BeginConnect(remoteIPAddress, remotePort, new AsyncCallback(AsyncConnect), mSocket);
} catch (Exception ex) {
DisplayError(KeyID, ex.Message);
}
return mSocket.Connected;
}
/// <summary>
/// 断开与主机的连接
/// </summary>
/// <returns></returns>
public bool Disconnect() {
try {
if (mSocket != null) {
if (mSocket.Connected) {
mSocket.Shutdown(SocketShutdown.Both);
mSocket.Close();
mSocket = null;
} else {
mSocket = null;
}
}
return true;
} catch (Exception ex) {
DisplayError(keyID, ex.Message);
return false;
}
}
/// <summary>
/// 发送消息(异步发送)
/// </summary>
/// <param name="aMessage">要发送的消息</param>
public void Send(string aMessage) {
string strMessage = aMessage;
//判断要发送的消息是不是以消息终止判断符号结尾,如果没有则自动加上
if (strMessage.Substring(strMessage.Length - 1, 1) != EndChar) {
strMessage = strMessage + EndChar;
}
Send(Encoding.UTF8.GetBytes(strMessage));
}
/// <summary>
/// 发送消息(异步发送)
/// </summary>
/// <param name="aMessage">要发送的消息</param>
public void Send(byte[] aMessage, int aMessageLength) {
StringBuilder SendBuffer = new StringBuilder();
SendBuffer.Append(Encoding.UTF8.GetString(aMessage, 0, aMessageLength));
string strSend = SendBuffer.ToString();
Send(strSend);
}
#endregion
}
}
- 编写TCP异步通信组件之AsyncTCPClient
- 编写TCP异步通信组件之AsyncTCPServer
- 编写TCP异步通信组件之SocketObject
- .NET下可复用的TCP通信层实现之TCP组件
- 异步socket TCP 通信
- 异步TCP通信-select
- 【06】 Boost库学习笔记之异步通信(TCP)
- .NET可复用TCP通信层之消息分派器组件
- BOOST TCP 异步 网络通信
- Python网络通信之socket模块(四)基于Tcp/Ip的TCP交互通信serve/client的编写过程
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(源代码)
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(客户端-源代码)
- c#中异步基于消息通信的完成端口的TCP-IP协议的组件实现(服务器端-源代码)
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(源代码) 服务器端
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(源代码) 客户端
- c#中异步基于消息通信的完成端口的TCP/IP协议的组件实现(源代码) 客户端
- TCP通信之Socket
- LWIP之TCP通信
- 需求决定设计,设计来源于需求(转个帖子)
- 让datagridview或girdview指定的一行或多行变色
- This application is currently offline...异常
- 编写TCP异步通信组件之AsyncTCPServer
- 发表文章报.text错误的bug已修正
- 编写TCP异步通信组件之AsyncTCPClient
- 查看本机网络属性的VBS
- SQL-left join的总结
- apache 定制日志
- 编写TCP异步通信组件之SocketObject
- appfuse下使用ibatis的一般步骤和若干问题
- .net 2.0 下发送邮件的方式。System.Web.Mail 过时用System.Net.Mail
- MD5 在线加密
- 兔子的悲哀