384 lines
14 KiB
C#
384 lines
14 KiB
C#
namespace LSServerService
|
|
{
|
|
using LSUtils;
|
|
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
|
|
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)
|
|
{
|
|
LSWriteLog.WriteString("RecordSocketCloseReason.log", "socket.Handle= {0},_socket.Connected= {1},ErrorCode= {2}", new object[] { this._socket.Handle, this._socket.Connected, 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();
|
|
LSWriteLog.WriteLog("SocketCloseInfo.log", true, "closesocket : socketid={0} _socketstate={1},RemotePort= {2} ", new object[] { this._socket.Handle.ToString(), this._socketstate, str });
|
|
this._socket.Shutdown(SocketShutdown.Receive);
|
|
Thread.Sleep(1);
|
|
this._socket.Close();
|
|
}
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.CloseSocket SOCKET errorcode: {0} errormsg: {1} _socketstate={2}", new object[] { exception.SocketErrorCode, exception, this._socketstate });
|
|
}
|
|
catch (Exception exception2)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.CloseSocket error: {0}", new object[] { exception2 });
|
|
}
|
|
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)
|
|
{
|
|
PubUtils.WriteLog("ReceiveCallback error: {0}", new object[] { 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)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.ReceiveReady socket error: {0}", new object[] { exception });
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception exception2)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.ReceiveReady error: {0}", new object[] { exception2 });
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
PubUtils.WriteLog(this.ToString() + ".send 过程即将要发送数据,但是不能发出去,socket = null, _socketstate=={0}, 要发送的数据内容是:\n{1}", new object[] { this._socketstate, byteData });
|
|
}
|
|
else
|
|
{
|
|
PubUtils.WriteLog(this.ToString() + ".send 过程即将要发送数据,但是不能发出去,socket id= {0}, socket.Connected=={1},_socketstate=={2}, 要发送的数据内容是:\n{3}", new object[] { 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;
|
|
}
|
|
LSWriteLog.WriteString("SocketSendDataWaitOneTime.log", "Socket Send Data WaitOne过程等待周期 = {0}", new object[] { 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();
|
|
PubUtils.WriteLog("LSASyncSocket.Sen SOCKET errorcode: {0} errormsg: {1}", new object[] { exception.SocketErrorCode, exception });
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception exception2)
|
|
{
|
|
this.SendDone_Event.Set();
|
|
PubUtils.WriteLog("LSASyncSocket.Send error: {0}", new object[] { exception2 });
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void SendCallback(IAsyncResult ar)
|
|
{
|
|
if (((this._socket == null) || !this._socket.Connected) || (this._socketstate == 2))
|
|
{
|
|
LSWriteLog.WriteTrace("{0}.SendCallback send state,_socket= {1} ,_socket.Connected= {2}, _socketstate= {3}", new object[] { this, this._socket.Handle, this._socket.Connected, this._socketstate });
|
|
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)
|
|
{
|
|
PubUtils.WriteLog("严重错误!!!需要发送的长度是= {0},但实际发送的长度为= {1}", new object[] { this._SendedLen, this.nSendLength });
|
|
this.CloseSocket();
|
|
}
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.SendCallback SOCKET errorcode: {0} errormsg: {1}, ", new object[] { exception.SocketErrorCode, exception.Message.ToString() });
|
|
this.CheckCloseState(exception.ErrorCode);
|
|
}
|
|
catch (Exception exception2)
|
|
{
|
|
if (this._socket == null)
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.SendCallback error: {0}, _socket=null,this={1}", new object[] { exception2, this });
|
|
}
|
|
else
|
|
{
|
|
PubUtils.WriteLog("LSASyncSocket.SendCallback error: {0}, socket id={1},_socket.Connected={2},_socketstate={3},this={4}", new object[] { exception2, this._socket.Handle, this._socket.Connected, this._socketstate, this });
|
|
}
|
|
}
|
|
asyncState = Environment.TickCount - asyncState;
|
|
LSWriteLog.WriteString("SocketSendDataCostTime.log", "Socket Send Data周期(包含WaitOne) = {0}", new object[] { 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|