You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

419 lines
14 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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