using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
namespace Common.TcpLib
{
/// <summary>
/// 异步Socket处理客户端
/// </summary>
public class TcpClientY : Common.TcpLib.ITcpClient
{
public Socket _clientSocket;
private string _serverIp;
private int _port;
private int _bufferSize = 1024;
private bool _disposed = false;
private bool _debug = false;
private ManualResetEvent sendDone = new ManualResetEvent(false);
private object _stopLock = new object();
private bool _sotpMessage = false;
#region define delegates
/// <summary>
/// 连接上服务器后的事件处理
/// </summary>
public _Bgz_OnConnectEventDelegate FOnConnectEventDelegate;
/// <summary>
/// 接收服务端发来的数据事件处理
/// </summary>
public _Bgz_OnReceiveBeginEventDelegate FOnReceiveBeginEventDelegate;
/// <summary>
/// 接收服务端发来的数据事件处理
/// </summary>
public _Bgz_OnReceiveingEventDelegate FOnReceiveingEventDelegate;
/// <summary>
/// 接收服务端发来的数据事件处理
/// </summary>
public _Bgz_OnReceiveEndEventDelegate FOnReceiveEndEventDelegate;
/// <summary>
/// 报错信息处理
/// </summary>
public _Bgz_OnErrorEventDelegate FOnErrorEventDelegate;
#endregion
#region Event
private void OnConnectEvent(_Bgz_ConnectionState state)
{
if (FOnConnectEventDelegate != null) FOnConnectEventDelegate(state);
}
private void OnReceiveBeginEvent(_Bgz_ConnectionState state)
{
if (FOnReceiveBeginEventDelegate != null) FOnReceiveBeginEventDelegate(state);
}
private void OnReceiveingEvent(_Bgz_ConnectionState state)
{
if (FOnReceiveingEventDelegate != null) FOnReceiveingEventDelegate(state);
}
private void OnReceiveEndEvent(_Bgz_ConnectionState state)
{
if (FOnReceiveEndEventDelegate != null) FOnReceiveEndEventDelegate(state);
}
private void OnErrorEvent(ErrorType errortype, string msg, _Bgz_ConnectionState state)
{
if (FOnErrorEventDelegate != null) FOnErrorEventDelegate(errortype, msg, state);
}
#endregion
#region property
public int BufferSize
{
get
{
return _bufferSize;
}
}
public bool Debug
{
get
{
return _debug;
}
set
{
_debug = value;
}
}
#endregion
#region Constructor and Destructor
public TcpClientY(string serverIp, int port)
{
this._serverIp = serverIp;
this._port = port;
}
public TcpClientY(string serverIp, int port, int bufferSize)
{
this._serverIp = serverIp;
this._port = port;
this._bufferSize = bufferSize;
}
~TcpClientY()
{
if (!_disposed)
{
Stop();
}
}
#endregion
#region Private Methods
private void Dispose()
{
if (!_disposed)
{
Stop();
GC.Collect();
GC.WaitForPendingFinalizers();
this.FOnConnectEventDelegate = null;
this.FOnErrorEventDelegate = null;
this.FOnReceiveBeginEventDelegate = null;
this.FOnReceiveEndEventDelegate = null;
this.FOnReceiveingEventDelegate = null;
_disposed = true;
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
_Bgz_ConnectionState stx = ar.AsyncState as _Bgz_ConnectionState;
OnReceiveBeginEvent(stx);
stx._conn.EndReceive(ar);
if (stx._conn.Available == 0)
{
Stop();
return;
}
#region receive
lock (ar)
{
stx._count = 0;
stx._dataStream.SetLength(0);
stx._dataStream.Position = 0;
if (stx._getonceall)
{
stx._buffer = new byte[stx.AvailableData];
int ret = stx.Read(stx._buffer, 0, stx._buffer.Length);
if (ret > 0)
{
stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
stx._count++;
OnReceiveingEvent(stx);
}
}
else
{
while (stx.AvailableData > 0)
{
if (stx.AvailableData > _bufferSize)
stx._buffer = new byte[_bufferSize];
else
stx._buffer = new byte[stx.AvailableData];
int ret = stx.Read(stx._buffer, 0, stx._buffer.Length);
if (ret > 0)
{
stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
stx._count++;
OnReceiveingEvent(stx);
}
}
}
}
#endregion
OnReceiveEndEvent(stx);
if (stx.Connected)
stx._conn.BeginReceive(stx._buffer, 0, 0, SocketFlags.None, new AsyncCallback(ReceiveCallback), stx);
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "ReceiveCallback Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
private void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
finally
{
sendDone.Set();
}
}
#endregion
#region Public Methods
public void Connect()
{
try
{
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_clientSocket.Connect(new IPEndPoint(IPAddress.Parse(_serverIp), _port));
_Bgz_ConnectionState stx = new _Bgz_ConnectionState();
stx._conn = this._clientSocket;
OnConnectEvent(stx);
_stopLock = new object();
_sotpMessage = false;
_clientSocket.BeginReceive(stx._buffer, 0, 0, SocketFlags.None, new AsyncCallback(ReceiveCallback), stx);
}
catch (Exception ex)
{
OnErrorEvent(ErrorType.Catch, "连接到远程服务器" + _serverIp + ":" + _port.ToString() + "失败!\r\n" + ex.Message, null);
}
}
public void Send(byte[] msg)
{
try
{
if (_clientSocket.Connected)
_clientSocket.Send(msg);
else
{
_Bgz_ConnectionState stx = new _Bgz_ConnectionState();
stx._conn = this._clientSocket;
stx._buffer = msg;
OnErrorEvent(ErrorType.DisConnect, "未与服务器建立链接,导致发送数据失败!", stx);
}
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
public void SendAsync(byte[] msg)
{
try
{
if (_clientSocket.Connected == false)
{
throw (new Exception("没有连接客户端不可以发送信息!"));
}
byte[] buffer;
int count = msg.Length;
int cur = 0;
while (count > 0)
{
if (count > this._bufferSize)
buffer = new byte[_bufferSize];
else
buffer = new byte[count];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = msg[cur + i];
}
count -= buffer.Length;
cur += buffer.Length;
_clientSocket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), _clientSocket);
sendDone.WaitOne();
}
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
public void SendAsync(Stream Astream)
{
try
{
if (_clientSocket.Connected == false)
{
throw (new Exception("没有连接客户端不可以发送信息!"));
}
byte[] buffer;
long count = Astream.Length;
while (count > 0)
{
if (count > this._bufferSize)
buffer = new byte[this._bufferSize];
else
buffer = new byte[count];
Astream.Read(buffer, 0, buffer.Length);
count -= buffer.Length;
_clientSocket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), _clientSocket);
sendDone.WaitOne();
}
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
public void Stop()
{
try
{
if (_clientSocket != null)
{
if (_clientSocket.Connected)
{
_clientSocket.Shutdown(SocketShutdown.Both);
_clientSocket.Disconnect(false);
}
_clientSocket.Close();
}
lock (_stopLock)
{
if (!_sotpMessage)
{
OnErrorEvent(ErrorType.DisConnect, "关闭了与服务器的连接!", null);
_sotpMessage = true;
}
}
}
catch (Exception ex)
{
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Stop Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
#endregion
}
}