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 } }