ab56a9bcf7
SVN-Revision: r240
366 lines
12 KiB
C#
366 lines
12 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using Lskj.Util;
|
|
|
|
namespace Lskj.AttachStart.Service
|
|
{
|
|
public abstract class LSASyncSocket
|
|
{
|
|
private byte _HandledCloseEventCounter = 0;
|
|
private int _LastExchangeStamp = 0;
|
|
protected int _ReceivedLen = 0;
|
|
private int _SendedLen = 0;
|
|
protected Socket _socket;
|
|
protected int _socketstate = 0;
|
|
private object[] _source;
|
|
private int nSendLength = 0;
|
|
public object ObjClient2Server = 2;
|
|
public object ObjServer2Client = 1;
|
|
protected const uint PACKETMAXLEN = 102400;
|
|
private AutoResetEvent RevDone_Event = new AutoResetEvent(true);
|
|
private AutoResetEvent SendDone_Event = new AutoResetEvent(true);
|
|
protected StateObject StateObj = new StateObject();
|
|
|
|
public event SocketCloseEventHandle SocketCloseEvent;
|
|
|
|
protected LSASyncSocket()
|
|
{
|
|
}
|
|
|
|
protected void CheckCloseState(int ErrorCode)
|
|
{
|
|
switch (ErrorCode)
|
|
{
|
|
case 10053:
|
|
case 10054:
|
|
case 10057:
|
|
case 10058:
|
|
this.CloseSocket();
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void CloseSocket()
|
|
{
|
|
if (this._socketstate != 2)
|
|
{
|
|
try
|
|
{
|
|
this._socketstate = 2;
|
|
if ((this._socket != null) && this._socket.Connected)
|
|
{
|
|
string str = ((IPEndPoint)this._socket.RemoteEndPoint).Port.ToString();
|
|
this._socket.Shutdown(SocketShutdown.Receive);
|
|
Thread.Sleep(1);
|
|
this._socket.Close();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.WriteError(ex);
|
|
}
|
|
if (this.SocketCloseEvent != null)
|
|
{
|
|
this.SocketCloseEvent(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void ContinueReceive()
|
|
{
|
|
try
|
|
{
|
|
if (((this._socket != null) && this._socket.Connected) && (this._socketstate != 2))
|
|
{
|
|
this._ReceivedLen = 0;
|
|
if (this.StateObj.buffer.Length > this.StateObj.BufferSize)
|
|
{
|
|
this.StateObj.buffer = new byte[this.StateObj.BufferSize];
|
|
}
|
|
this.SetLastStamp();
|
|
this._socket.BeginReceive(this.StateObj.buffer, 0, this.StateObj.BufferSize, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), this._socket);
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogHelper.Instance.WriteError(exception);
|
|
}
|
|
}
|
|
|
|
~LSASyncSocket()
|
|
{
|
|
if (this.SendDone_Event != null)
|
|
{
|
|
this.SendDone_Event.Close();
|
|
this.SendDone_Event = null;
|
|
}
|
|
if (this.RevDone_Event != null)
|
|
{
|
|
this.RevDone_Event.Close();
|
|
this.RevDone_Event = null;
|
|
}
|
|
}
|
|
|
|
public void HandledCloseEvent()
|
|
{
|
|
this._HandledCloseEventCounter = (byte)(this._HandledCloseEventCounter + 1);
|
|
}
|
|
|
|
protected abstract void ParseReceiveData(byte[] byteData);
|
|
protected abstract void ReceiveCallback(IAsyncResult ar);
|
|
protected void ReceiveReady()
|
|
{
|
|
this._socketstate = 1;
|
|
this._ReceivedLen = 0;
|
|
try
|
|
{
|
|
this._socket.BeginReceive(this.StateObj.buffer, 0, this.StateObj.BufferSize, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), this._socket);
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.WriteError(ex);
|
|
}
|
|
}
|
|
|
|
public bool Send(object structObj)
|
|
{
|
|
byte[] byteData = PubUtils.StructToBytes(structObj);
|
|
return this.Send(byteData);
|
|
}
|
|
|
|
public bool Send(byte[] byteData)
|
|
{
|
|
return this.Send(byteData, byteData.Length);
|
|
}
|
|
|
|
public bool Send(byte[] byteData, int sendLength)
|
|
{
|
|
int tickCount = Environment.TickCount;
|
|
if (((this._socket == null) || !this._socket.Connected) || (this._socketstate == 2))
|
|
{
|
|
if (this._socket == null)
|
|
{
|
|
LogHelper.Instance.WriteLog(string.Format(this.ToString() + ".send 过程即将要发送数据,但是不能发出去,socket = null, _socketstate=={0}, 要发送的数据内容是:\n{1}", this._socketstate, byteData));
|
|
}
|
|
else
|
|
{
|
|
LogHelper.Instance.WriteLog(string.Format(this.ToString() + ".send 过程即将要发送数据,但是不能发出去,socket id= {0}, socket.Connected=={1},_socketstate=={2}, 要发送的数据内容是:\n{3}", this._socket.Handle, this._socket.Connected, this._socketstate, byteData));
|
|
}
|
|
return false;
|
|
}
|
|
this.SendDone_Event.WaitOne();
|
|
if (((this._socket == null) || !this._socket.Connected) || (this._socketstate == 2))
|
|
{
|
|
this.SendDone_Event.Set();
|
|
return false;
|
|
}
|
|
LogHelper.Instance.WriteLog(string.Format("Socket Send Data WaitOne过程等待周期 = {0}", Environment.TickCount - tickCount));
|
|
this.SetLastStamp();
|
|
this._SendedLen = 0;
|
|
this.nSendLength = sendLength;
|
|
try
|
|
{
|
|
this._socket.BeginSend(byteData, 0, sendLength, SocketFlags.None, new AsyncCallback(this.SendCallback), tickCount);
|
|
return true;
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
this.SendDone_Event.Set();
|
|
LogHelper.Instance.WriteLog(string.Format("LSASyncSocket.Sen SOCKET errorcode: {0} errormsg: {1}", exception.SocketErrorCode, exception.StackTrace));
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.SendDone_Event.Set();
|
|
LogHelper.Instance.WriteError(ex);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void SendCallback(IAsyncResult ar)
|
|
{
|
|
if (((this._socket == null) || !this._socket.Connected) || (this._socketstate == 2))
|
|
{
|
|
this.SendDone_Event.Set();
|
|
}
|
|
else
|
|
{
|
|
int asyncState = 2147483647;
|
|
try
|
|
{
|
|
asyncState = (int)ar.AsyncState;
|
|
int num2 = this._socket.EndSend(ar);
|
|
this._SendedLen += num2;
|
|
if (this.nSendLength != this._SendedLen)
|
|
{
|
|
LogHelper.Instance.WriteLog(string.Format("严重错误!!!需要发送的长度是= {0},但实际发送的长度为= {1}", this._SendedLen, this.nSendLength));
|
|
this.CloseSocket();
|
|
}
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Instance.WriteError(ex);
|
|
}
|
|
asyncState = Environment.TickCount - asyncState;
|
|
LogHelper.Instance.WriteLog(string.Format("Socket Send Data周期(包含WaitOne) = {0}", asyncState));
|
|
this.SendDone_Event.Set();
|
|
}
|
|
}
|
|
|
|
public void SetLastStamp()
|
|
{
|
|
this._LastExchangeStamp = Environment.TickCount;
|
|
}
|
|
|
|
private void SetOptBuffer(int SendBufSize, int RevBufSize)
|
|
{
|
|
if (SendBufSize <= 0)
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, 1024);
|
|
}
|
|
else
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, SendBufSize);
|
|
}
|
|
if (RevBufSize <= 0)
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 1024);
|
|
}
|
|
else
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, RevBufSize);
|
|
}
|
|
}
|
|
|
|
private void SetOptKeepAlive()
|
|
{
|
|
uint num = 10000;
|
|
uint num2 = 2000;
|
|
uint structure = 0;
|
|
byte[] array = new byte[Marshal.SizeOf(structure) * 3];
|
|
BitConverter.GetBytes((uint)1).CopyTo(array, 0);
|
|
BitConverter.GetBytes(num).CopyTo(array, Marshal.SizeOf(structure));
|
|
BitConverter.GetBytes(num2).CopyTo(array, (int)(Marshal.SizeOf(structure) * 2));
|
|
this._socket.IOControl(IOControlCode.KeepAliveValues, array, null);
|
|
}
|
|
|
|
private void SetOptLinger(int nMilliSecond)
|
|
{
|
|
LingerOption optionValue = null;
|
|
if (nMilliSecond <= 0)
|
|
{
|
|
optionValue = new LingerOption(true, 1000);
|
|
}
|
|
else
|
|
{
|
|
optionValue = new LingerOption(true, nMilliSecond);
|
|
}
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, optionValue);
|
|
}
|
|
|
|
private void SetOptTimeOut(int nMilliSecond)
|
|
{
|
|
if (nMilliSecond <= 0)
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
|
|
}
|
|
else
|
|
{
|
|
this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, nMilliSecond);
|
|
}
|
|
}
|
|
|
|
public bool TimeOutCheck(int TimeOutValue)
|
|
{
|
|
return ((Environment.TickCount - this._LastExchangeStamp) > TimeOutValue);
|
|
}
|
|
|
|
public bool HandledCloseEventCounter
|
|
{
|
|
get
|
|
{
|
|
return (this._HandledCloseEventCounter > 0);
|
|
}
|
|
}
|
|
|
|
public int ReceivedLen
|
|
{
|
|
get
|
|
{
|
|
return this._ReceivedLen;
|
|
}
|
|
}
|
|
|
|
public int SendedLen
|
|
{
|
|
get
|
|
{
|
|
return this._SendedLen;
|
|
}
|
|
}
|
|
|
|
public Socket socket
|
|
{
|
|
get
|
|
{
|
|
return this._socket;
|
|
}
|
|
}
|
|
|
|
public int SocketState
|
|
{
|
|
get
|
|
{
|
|
return this._socketstate;
|
|
}
|
|
}
|
|
|
|
public object[] source
|
|
{
|
|
get
|
|
{
|
|
return this._source;
|
|
}
|
|
set
|
|
{
|
|
this._source = value;
|
|
}
|
|
}
|
|
|
|
public delegate void SocketCloseEventHandle(LSASyncSocket AsyncSocket);
|
|
|
|
protected class StateObject
|
|
{
|
|
private const int _BufferSize = 10240;
|
|
public byte[] buffer = new byte[10240];
|
|
|
|
public void ExtentBuffer()
|
|
{
|
|
int num = this.buffer.Length * 2;
|
|
byte[] dst = new byte[num];
|
|
Buffer.BlockCopy(this.buffer, 0, dst, 0, this.buffer.Length);
|
|
this.buffer = dst;
|
|
}
|
|
|
|
public int BufferSize
|
|
{
|
|
get
|
|
{
|
|
return 10240;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |