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 static 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;
public bool isConnet
{
get
{
return clientSocket != null;
}
}
///
/// 初始化客户端
///
/// 服务端地址{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.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);
//clientSocket.ConnectAsync(listenerSocketAsyncEventArgs);
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()
{
ICSharpCode.Core.LoggingService.Debug("开始侦听...");
//receiveThread = new Thread(new ThreadStart(Listen));
lastRecieveTime = DateTime.Now;
Listen();
}
///
/// 开始监听线程的入口函数
///
public void Listen()
{
try
{
(listenerSocketAsyncEventArgs.UserToken as Socket).ReceiveAsync(listenerSocketAsyncEventArgs);
}
catch(Exception ex)
{
//Console.WriteLine(ex.Message);
}
}
public void Close()
{
this.clientSocket.Close();
}
public void ReConnect()
{
try
{
if (this.clientSocket != null && this.clientSocket.Connected)
{
this.clientSocket.Disconnect(false);
this.Close();
this.clientSocket = null;
}
//this.clientSocket.Close();
this.hostEndPoint = new IPEndPoint(IPAddress.Parse(hostName), int.Parse(port));
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
this.Connect();
this.Send("0a0b0c");
}
catch (System.Exception e)
{
Console.WriteLine("网络已经断开" + e.ToString());
ICSharpCode.Core.LoggingService.Error("网络已经断开"+e.ToString());
}
}
///
/// 停止监听线程
///
public void StopListenThread()
{
receiveThread.Abort();
listenerSocketAsyncEventArgs.Dispose();
listenerSocketAsyncEventArgs = null;
//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.Disconnect();
ICSharpCode.Core.LoggingService.Info("发送数据失败,socket退出");
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()
{
if (this.clientSocket != null)
{
try
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Disconnect(false);
connected = false;
clientSocket.Close();
clientSocket = null;
StopListenThread();
}
catch (Exception e)
{
ICSharpCode.Core.LoggingService.Error(e.ToString());
}
}
}
///
/// 连接的完成方法
///
///
///
private void OnConnect(object sender, SocketAsyncEventArgs e)
{
Console.WriteLine("连接完成方法");
autoConnectEvent.Set();
this.connected = (e.SocketError == SocketError.Success);
}
///
/// 接收的完成方法
///
///
///
private void OnReceive(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred<1)
{
ICSharpCode.Core.LoggingService.Info("接收到数据空数据:");
//这是不是可以重新连接
this.Disconnect();
this.Connect();
return;
}
//Console.WriteLine("接收到数据" + msg);
lastRecieveTime = DateTime.Now;
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);
}
}
}
///
/// 处理错误
///
///
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);
}
#region IDisposable Members
public void Dispose()
{
autoConnectEvent.Close();
if (clientSocket != null&&this.clientSocket.Connected)
{
this.clientSocket.Close();
}
}
#endregion
}
}