|
|
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;
|
|
|
/// <summary>
|
|
|
/// 客户端连接Socket
|
|
|
/// </summary>
|
|
|
private Socket clientSocket;
|
|
|
/// <summary>
|
|
|
/// 连接状态
|
|
|
/// </summary>
|
|
|
private Boolean connected = false;
|
|
|
/// <summary>
|
|
|
/// 连接点
|
|
|
/// </summary>
|
|
|
private IPEndPoint hostEndPoint;
|
|
|
/// <summary>
|
|
|
/// 连接信号量
|
|
|
/// </summary>
|
|
|
private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);
|
|
|
/// <summary>
|
|
|
/// 接受到数据时的委托
|
|
|
/// </summary>
|
|
|
/// <param name="info"></param>
|
|
|
public delegate void ReceiveMsgHandler(SocketMessage info);
|
|
|
/// <summary>
|
|
|
/// 接收到数据时调用的事件
|
|
|
/// </summary>
|
|
|
public event ReceiveMsgHandler OnMsgReceived;
|
|
|
/// <summary>
|
|
|
/// 开始监听数据的委托
|
|
|
/// </summary>
|
|
|
public delegate void StartListenHandler();
|
|
|
/// <summary>
|
|
|
/// 开始监听数据的事件
|
|
|
/// </summary>
|
|
|
public event StartListenHandler StartListenThread;
|
|
|
/// <summary>
|
|
|
/// 发送信息完成的委托
|
|
|
/// </summary>
|
|
|
/// <param name="successorfalse"></param>
|
|
|
public delegate void SendCompleted(bool successorfalse);
|
|
|
/// <summary>
|
|
|
/// 发送信息完成的事件
|
|
|
/// </summary>
|
|
|
public event SendCompleted OnSended;
|
|
|
/// <summary>
|
|
|
/// 监听接收的SocketAsyncEventArgs
|
|
|
/// </summary>
|
|
|
private SocketAsyncEventArgs listenerSocketAsyncEventArgs;
|
|
|
/// <summary>
|
|
|
/// 监听线程
|
|
|
/// </summary>
|
|
|
Thread receiveThread = null;
|
|
|
public string hostName;
|
|
|
public string port;
|
|
|
public DateTime lastRecieveTime;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 初始化客户端
|
|
|
/// </summary>
|
|
|
/// <param name="hostName">服务端地址{IP地址}</param>
|
|
|
/// <param name="port">端口号</param>
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 连接服务端
|
|
|
/// </summary>
|
|
|
public bool Connect()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (clientSocket == null)
|
|
|
{
|
|
|
Init();
|
|
|
}
|
|
|
SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
|
|
|
connectArgs.UserToken = this.clientSocket;
|
|
|
connectArgs.RemoteEndPoint = this.hostEndPoint;
|
|
|
connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(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<SocketAsyncEventArgs>(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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 开始监听线程的入口函数
|
|
|
/// </summary>
|
|
|
public void Listen()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
Socket socket = listenerSocketAsyncEventArgs.UserToken as Socket;
|
|
|
if (socket != null)
|
|
|
{
|
|
|
socket.ReceiveAsync(listenerSocketAsyncEventArgs);
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
//Console.WriteLine(ex.Message);
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 停止监听线程
|
|
|
/// </summary>
|
|
|
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();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发送信息
|
|
|
/// </summary>
|
|
|
/// <param name="message"></param>
|
|
|
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<SocketAsyncEventArgs>(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<SocketAsyncEventArgs>(OnSend);
|
|
|
clientSocket.SendAsync(senderSocketAsyncEventArgs);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Disconnect();
|
|
|
ICSharpCode.Core.LoggingService.Info("发送数据失败,socket退出");
|
|
|
throw new SocketException((Int32)SocketError.NotConnected);
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 断开连接
|
|
|
/// </summary>
|
|
|
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();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 连接的完成方法
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
private void OnConnect(object sender, SocketAsyncEventArgs e)
|
|
|
{
|
|
|
//Console.WriteLine("连接完成方法");
|
|
|
autoConnectEvent.Set();
|
|
|
this.connected = (e.SocketError == SocketError.Success);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 接收的完成方法
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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();
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 发送的完成方法
|
|
|
/// </summary>
|
|
|
/// <param name="sender"></param>
|
|
|
/// <param name="e"></param>
|
|
|
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();
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 处理错误
|
|
|
/// </summary>
|
|
|
/// <param name="e"></param>
|
|
|
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
|
|
|
}
|
|
|
}
|