using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Configuration;
using Mesnac.Compressor.Entity;
namespace SocketProcess
{
public class SocketClient : IDisposable
{
// private static SocketClient instance = null;
///
/// 客户端连接Socket
///
private Socket clientSocket;
///
/// 连接状态
///
private Boolean connected = false;
///
/// 连接点
///
private IPEndPoint hostEndPoint;
///
/// 连接信号量
///
private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);
///
/// 接受到数据时的委托
///
///
public delegate void ReceiveMsgHandler(SocketMessage info);
///
/// 接收到数据时调用的事件
///
public event ReceiveMsgHandler OnMsgReceived;
///
/// 开始监听数据的委托
///
public delegate void StartListenHandler();
///
/// 开始监听数据的事件
///
public event StartListenHandler StartListenThread;
///
/// 发送信息完成的委托
///
///
public delegate void SendCompleted(bool successorfalse);
///
/// 发送信息完成的事件
///
public event SendCompleted OnSended;
///
/// 监听接收的SocketAsyncEventArgs
///
private SocketAsyncEventArgs listenerSocketAsyncEventArgs;
///
/// 监听线程
///
Thread receiveThread = null;
public string hostName;
public string port;
public DateTime lastRecieveTime;
///
/// 初始化客户端
///
/// 服务端地址{IP地址}
/// 端口号
public SocketClient(string hostName, string port)//String hostName, Int32 port
{
this.hostName = hostName;
this.port = port;
Init();
//Connect();
}
public void Init()
{
object listenServerIP = this.hostName;//ConfigurationManager.AppSettings["ListenServerIP"];
string oport = this.port;//ConfigurationManager.AppSettings["Port"].ToString();
string hostName = listenServerIP.ToString();
int port = 0;
int.TryParse(oport, out port);
IPAddress ip = IPAddress.Parse(hostName);
//IPEndPoint ipe = new IPEndPoint(ip, port);
//IPHostEntry host = IP//Dns.GetHostEntry(hostName);
//IPAddress[] addressList = host.AddressList;
this.hostEndPoint = new IPEndPoint(ip, port);
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
///
/// 连接服务端
///
public bool Connect()
{
try
{
if (clientSocket == null)
{
Init();
}
SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
connectArgs.UserToken = this.clientSocket;
connectArgs.RemoteEndPoint = this.hostEndPoint;
connectArgs.Completed += new EventHandler(OnConnect);
clientSocket.ConnectAsync(connectArgs);
//等待连接结果
autoConnectEvent = new AutoResetEvent(false);
autoConnectEvent.WaitOne();
SocketError errorCode = connectArgs.SocketError;
if (errorCode == SocketError.Success)
{
listenerSocketAsyncEventArgs = new SocketAsyncEventArgs();
byte[] receiveBuffer = new byte[32768];
listenerSocketAsyncEventArgs.UserToken = clientSocket;
listenerSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
listenerSocketAsyncEventArgs.Completed += new EventHandler(OnReceive);
StartListenThread += new SocketClient.StartListenHandler(listener_StartListenThread);
StartListenThread();
return true;
}
else
{
Console.WriteLine(errorCode.ToString());
throw new SocketException((Int32)errorCode);
//return false;
}
}
catch(Exception e)
{
Console.WriteLine("Socket异常:"+e.ToString());
return false;
}
}
private void listener_StartListenThread()
{
Mesnac.Log.LogService.Instance.Debug("开始侦听...");
//receiveThread = new Thread(new ThreadStart(Listen));
Listen();
}
///
/// 开始监听线程的入口函数
///
public void Listen()
{
try
{
Socket socket = listenerSocketAsyncEventArgs.UserToken as Socket;
if (socket != null)
{
socket.ReceiveAsync(listenerSocketAsyncEventArgs);
}
}
catch(Exception ex)
{
//Console.WriteLine(ex.Message);
}
}
///
/// 停止监听线程
///
public void StopListenThread()
{
try
{
if (StartListenThread != null)
{
StartListenThread -= new SocketClient.StartListenHandler(listener_StartListenThread);
}
if (receiveThread != null)
{
receiveThread.Abort();
}
if (clientSocket != null)
clientSocket.Close();
clientSocket = null;
//autoConnectEvent.Dispose();
Dispose();
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService.Error("停止监听线程异常:", ex);
}
//receiveThread.Abort();
//if (clientSocket != null)
// clientSocket.Close();
//clientSocket = null;
// Dispose();
}
///
/// 发送信息
///
///
public void Send(String message)
{
if (this.connected)
{
//message = String.Format("[length={0}]{1}", message.Length, message);
//Byte[] sendBuffer = Encoding.Unicode.GetBytes(message);
//Byte[] sendBuffer = System.Text.Encoding.Default.GetBytes(message);
Byte[] sendBuffer = StringToByte(message);
SocketAsyncEventArgs senderSocketAsyncEventArgs = new SocketAsyncEventArgs();
senderSocketAsyncEventArgs.UserToken = this.clientSocket;
senderSocketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
senderSocketAsyncEventArgs.RemoteEndPoint = this.hostEndPoint;
senderSocketAsyncEventArgs.Completed += new EventHandler(OnSend);
clientSocket.SendAsync(senderSocketAsyncEventArgs);
}
else
{
this.ReConnect();
ICSharpCode.Core.LoggingService.Info("发送数据失败");
//throw new SocketException((Int32)SocketError.NotConnected);
}
}
private Byte[] StringToByte(string mes)
{
mes = mes.Replace(" ","");
int count=mes.Length / 2;
byte[] bt = new byte[count];
for (int i = 0; i < count;i++)
{
string sub=mes.Substring(i*2,2);
bt[i] = (byte)Convert.ToInt16(sub,16);
}
return bt;
}
public void Send(byte[] message)
{
if (this.connected)
{
//message = String.Format("[length={0}]{1}", message.Length, message);
////Byte[] sendBuffer = Encoding.Unicode.GetBytes(message);
//Byte[] sendBuffer = System.Text.Encoding.Default.GetBytes(message);
SocketAsyncEventArgs senderSocketAsyncEventArgs = new SocketAsyncEventArgs();
senderSocketAsyncEventArgs.UserToken = this.clientSocket;
senderSocketAsyncEventArgs.SetBuffer(message, 0, message.Length);
senderSocketAsyncEventArgs.RemoteEndPoint = this.hostEndPoint;
senderSocketAsyncEventArgs.Completed += new EventHandler(OnSend);
clientSocket.SendAsync(senderSocketAsyncEventArgs);
}
else
{
this.Disconnect();
ICSharpCode.Core.LoggingService.Info("发送数据失败,socket退出");
throw new SocketException((Int32)SocketError.NotConnected);
}
}
///
/// 断开连接
///
public void Disconnect()
{
lock (string.Empty)
{
if (clientSocket != null)
{
try
{
clientSocket.Shutdown(SocketShutdown.Both);
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService.Error(ex.Message, ex);
}
clientSocket.Disconnect(false);
StopListenThread();
//autoConnectEvent.Dispose();
}
}
}
///
/// 连接的完成方法
///
///
///
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
//Console.WriteLine("连接完成方法");
autoConnectEvent.Set();
this.connected = (e.SocketError == SocketError.Success);
}
///
/// 接收的完成方法
///
///
///
private void OnReceive(object sender, SocketAsyncEventArgs e)
{
string str = this.ByteToString(e);
if (e.BytesTransferred < 1 || string.IsNullOrEmpty(str))
{
ICSharpCode.Core.LoggingService.Info("连接断开,重新连接");
if (this.clientSocket != null)
{
this.Disconnect();
}
this.Connect();
//this.Disconnect();
return;
}
string msg = ByteToString(e);
//Console.WriteLine("接收到数据"+msg);
Listen();
SocketMessage sm = new SocketMessage();
sm.Message = msg;
sm.Client = this;
if (OnMsgReceived != null)
OnMsgReceived(sm);
}
private string ByteToString(SocketAsyncEventArgs e)
{
StringBuilder sb = new StringBuilder();
int count=e.BytesTransferred;
for (int i = 0; i < count;i++ )
{
sb.Append(e.Buffer[i].ToString("x2"));
}
return sb.ToString();
}
///
/// 发送的完成方法
///
///
///
private void OnSend(object sender, SocketAsyncEventArgs e)
{
if (OnSended != null)
{
if (e.SocketError == SocketError.Success)
{
OnSended(true);
}
else
{
OnSended(false);
//this.ProcessError(e);
}
}
//如果发送失败,重新连接
if (e.SocketError != SocketError.Success)
{
ReConnect();
}
}
///
/// 处理错误
///
///
private void ProcessError(SocketAsyncEventArgs e)
{
Socket s = e.UserToken as Socket;
if (s.Connected)
{
try
{
s.Shutdown(SocketShutdown.Both);
}
catch (Exception)
{
//client already closed
}
finally
{
if (s.Connected)
{
s.Close();
}
}
}
throw new SocketException((Int32)e.SocketError);
}
public void ReConnect()
{
try
{
ICSharpCode.Core.LoggingService.Error("重新连接网络");
this.Disconnect();
Thread.Sleep(500);
this.Connect();
}
catch (System.Exception ex)
{
ICSharpCode.Core.LoggingService.Error("网络已经断开" + ex.ToString());
}
}
#region IDisposable Members
public void Dispose()
{
autoConnectEvent.Close();
if (clientSocket != null&&this.clientSocket.Connected)
{
this.clientSocket.Close();
}
}
#endregion
}
}