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 TcpClientT : Common.TcpLib.ITcpClient
{
public Socket _clientSocket;
private string _serverIp;
private int _port;
private int _bufferSize = 1024;
private Thread _thread;
private ManualResetEvent sendDone = new ManualResetEvent(false);
private bool _disposed = false;
private bool _debug = 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 TcpClientT(string serverIp, int port)
{
this._serverIp = serverIp;
this._port = port;
}
public TcpClientT(string serverIp, int port, int bufferSize)
{
this._serverIp = serverIp;
this._port = port;
this._bufferSize = bufferSize;
}
~TcpClientT()
{
if (!_disposed)
{
Stop();
}
}
#endregion
#region Private Methods
private void Dispose()
{
if (!_disposed)
{
if (_thread != null) Stop();
GC.Collect();
GC.WaitForPendingFinalizers();
this.FOnConnectEventDelegate = null;
this.FOnErrorEventDelegate = null;
this.FOnReceiveBeginEventDelegate = null;
this.FOnReceiveEndEventDelegate = null;
this.FOnReceiveingEventDelegate = null;
_disposed = true;
}
}
private void ReceiveThread()
{
try
{
_Bgz_ConnectionState stx = new _Bgz_ConnectionState(_clientSocket);
while (true)
{
try
{
stx._buffer = new byte[0];
stx._count = 0;
stx._getonceall = false;
_clientSocket.Receive(stx._buffer);
if (_clientSocket.Available == 0)
{
Stop();
return;
}
OnReceiveBeginEvent(stx);
stx._count = 0;
stx._dataStream.SetLength(0);
stx._dataStream.Position = 0;
if (stx._getonceall)
{
stx._buffer = new byte[_clientSocket.Available];
int ret = _clientSocket.Receive(stx._buffer, 0, stx._buffer.Length, SocketFlags.None);
if (ret > 0)
{
stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
stx._count++;
OnReceiveingEvent(stx);
}
}
else
{
while (_clientSocket.Available > 0)
{
if (_clientSocket.Available > _bufferSize)
stx._buffer = new byte[_bufferSize];
else
stx._buffer = new byte[_clientSocket.Available];
int ret = _clientSocket.Receive(stx._buffer, 0, stx._buffer.Length, SocketFlags.None);
if (ret > 0)
{
stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
stx._count++;
OnReceiveingEvent(stx);
}
}
}
OnReceiveEndEvent(stx);
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "ReceiveThread.1 Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", stx);
}
break;
}
}
}
catch (Exception ex)
{
Stop();
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "ReceiveThread.2 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)
{
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
{
this._clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._clientSocket.Connect(new IPEndPoint(IPAddress.Parse(_serverIp), _port));
_Bgz_ConnectionState stx = new _Bgz_ConnectionState(_clientSocket);
OnConnectEvent(stx);
_sotpMessage = false;
_stopLock = new object();
_thread = new Thread(new ThreadStart(ReceiveThread));
_thread.Start();
}
catch (Exception ex)
{
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Connect Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
Stop();
}
}
public void Stop()
{
try
{
if (_clientSocket != null)
if (this._clientSocket.Connected) this._clientSocket.Close();
_thread.Abort();
_thread = null;
lock (_stopLock)
{
if (!_sotpMessage)
{
OnErrorEvent(ErrorType.DisAccept, "关闭与服务器的连接!", 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);
}
}
}
public void Send(byte[] msg)
{
try
{
if (_clientSocket.Connected == false)
{
throw (new Exception("没有连接成功不可以发送信息!"));
}
_clientSocket.Send(msg);
}
catch (Exception ex)
{
OnErrorEvent(ErrorType.Catch, ex.Message, 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)
{
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)
{
if (Debug)
{
OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
}
}
}
#endregion
}
}