diff --git a/Common/BufferManager.cs b/Common/BufferManager.cs index f6740e0b7..7b6ca4ce1 100644 --- a/Common/BufferManager.cs +++ b/Common/BufferManager.cs @@ -19,6 +19,28 @@ public class BufferManager int m_currentIndex; int m_bufferSize; + /// + /// Get the buffer + /// + public byte[] Buffer + { + get + { + return m_buffer; + } + } + + /// + /// Get the buffer + /// + public int BufferSize + { + get + { + return m_bufferSize; + } + } + /// /// Initializes a new instance of the class. /// @@ -44,35 +66,35 @@ public void InitBuffer() /// /// Assigns a buffer from the buffer pool to the specified SocketAsyncEventArgs object /// - /// true if the buffer was successfully set, else false - public bool SetBuffer(SocketAsyncEventArgs args) + /// A Tuple where Item1 is true if the buffer should be set, else false. + /// If Item1 is true then Item2 has the new offset, else 0. + /// + public Tuple SetBuffer() { - + int offset; if (m_freeIndexPool.Count > 0) { - args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize); + offset = m_freeIndexPool.Pop(); } else { if ((m_numBytes - m_bufferSize) < m_currentIndex) { - return false; + return new Tuple(false, 0); } - args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize); + offset = m_currentIndex; m_currentIndex += m_bufferSize; } - return true; + return new Tuple(true, offset); } /// - /// Removes the buffer from a SocketAsyncEventArg object. This frees the buffer back to the + /// Removes the buffer from a SocketAsyncEventArg object. This frees the buffer back to the /// buffer pool /// - public void FreeBuffer(SocketAsyncEventArgs args) + public void FreeBuffer(int offset) { - m_freeIndexPool.Push(args.Offset); - args.SetBuffer(null, 0, 0); + m_freeIndexPool.Push(offset); } - } } diff --git a/Common/SuperSocket.Common.Net35.csproj b/Common/SuperSocket.Common.Net35.csproj index 98c967939..68a19fabf 100644 --- a/Common/SuperSocket.Common.Net35.csproj +++ b/Common/SuperSocket.Common.Net35.csproj @@ -97,7 +97,6 @@ - diff --git a/Common/SuperSocket.Common.Net40.csproj b/Common/SuperSocket.Common.Net40.csproj index e9eb1dd14..c536f9b57 100644 --- a/Common/SuperSocket.Common.Net40.csproj +++ b/Common/SuperSocket.Common.Net40.csproj @@ -93,7 +93,6 @@ - diff --git a/Common/SuperSocket.Common.Net45.csproj b/Common/SuperSocket.Common.Net45.csproj index b88421402..993c198e1 100644 --- a/Common/SuperSocket.Common.Net45.csproj +++ b/Common/SuperSocket.Common.Net45.csproj @@ -95,7 +95,6 @@ - diff --git a/Protocols/WebSocket/WebSocketServer.cs b/Protocols/WebSocket/WebSocketServer.cs index e825210e0..b03f6a481 100644 --- a/Protocols/WebSocket/WebSocketServer.cs +++ b/Protocols/WebSocket/WebSocketServer.cs @@ -17,6 +17,7 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; using SuperSocket.WebSocket.Command; using SuperSocket.WebSocket.Config; using SuperSocket.WebSocket.Protocol; @@ -54,8 +55,9 @@ public class WebSocketServer : WebSocketServer /// Initializes a new instance of the class. /// /// The sub protocols. - public WebSocketServer(IEnumerable> subProtocols) - : base(subProtocols) + /// + public WebSocketServer(IEnumerable> subProtocols, ISocketFactory socketFactory = null) + : base(subProtocols, socketFactory) { } @@ -64,8 +66,9 @@ public WebSocketServer(IEnumerable> subProtocols) /// Initializes a new instance of the class. /// /// The sub protocol. - public WebSocketServer(ISubProtocol subProtocol) - : base(subProtocol) + /// + public WebSocketServer(ISubProtocol subProtocol, ISocketFactory socketFactory = null) + : base(subProtocol, socketFactory) { } @@ -73,8 +76,8 @@ public WebSocketServer(ISubProtocol subProtocol) /// /// Initializes a new instance of the class. /// - public WebSocketServer() - : base(new List>()) + public WebSocketServer(ISocketFactory socketFactory = null) + : base(new List>(), socketFactory) { } @@ -105,8 +108,9 @@ protected IBinaryDataConverter BinaryDataConverter /// Initializes a new instance of the class. /// /// The sub protocols. - public WebSocketServer(IEnumerable> subProtocols) - : this() + /// + public WebSocketServer(IEnumerable> subProtocols, ISocketFactory socketFactory = null) + : this(socketFactory) { if (!subProtocols.Any()) return; @@ -124,8 +128,9 @@ public WebSocketServer(IEnumerable> subProtocols /// Initializes a new instance of the class. /// /// The sub protocol. - public WebSocketServer(ISubProtocol subProtocol) - : this(new List> { subProtocol }) + /// + public WebSocketServer(ISubProtocol subProtocol, ISocketFactory socketFactory = null) + : this(new List> { subProtocol }, socketFactory) { } @@ -133,8 +138,8 @@ public WebSocketServer(ISubProtocol subProtocol) /// /// Initializes a new instance of the class. /// - public WebSocketServer() - : base(new WebSocketProtocol()) + public WebSocketServer(ISocketFactory socketFactory = null) + : base(new WebSocketProtocol(), socketFactory) { } diff --git a/SocketBase/AppServer.cs b/SocketBase/AppServer.cs index d61a6f0ae..dc1a6f842 100644 --- a/SocketBase/AppServer.cs +++ b/SocketBase/AppServer.cs @@ -15,6 +15,7 @@ using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Protocol; using SuperSocket.SocketBase.Security; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketBase { @@ -36,8 +37,9 @@ public AppServer() /// Initializes a new instance of the class. /// /// The Receive filter factory. - public AppServer(IReceiveFilterFactory receiveFilterFactory) - : base(receiveFilterFactory) + /// The socket factory. + public AppServer(IReceiveFilterFactory receiveFilterFactory, ISocketFactory socketFactory = null) + : base(receiveFilterFactory, socketFactory) { } @@ -63,8 +65,9 @@ public AppServer() /// Initializes a new instance of the class. /// /// The Receive filter factory. - public AppServer(IReceiveFilterFactory receiveFilterFactory) - : base(receiveFilterFactory) + /// The socket factory. + public AppServer(IReceiveFilterFactory receiveFilterFactory, ISocketFactory socketFactory) + : base(receiveFilterFactory, socketFactory) { } @@ -98,8 +101,9 @@ public AppServer() /// Initializes a new instance of the class. /// /// The protocol. - protected AppServer(IReceiveFilterFactory protocol) - : base(protocol) + /// The socket factory. + protected AppServer(IReceiveFilterFactory protocol, ISocketFactory socketFactory = null) + : base(protocol, socketFactory) { } diff --git a/SocketBase/AppServerBase.cs b/SocketBase/AppServerBase.cs index b2175882e..fce86c8f6 100644 --- a/SocketBase/AppServerBase.cs +++ b/SocketBase/AppServerBase.cs @@ -16,6 +16,7 @@ using SuperSocket.SocketBase.Protocol; using SuperSocket.SocketBase.Provider; using SuperSocket.SocketBase.Security; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketBase { @@ -82,6 +83,14 @@ object IAppServer.ReceiveFilterFactory get { return this.ReceiveFilterFactory; } } + /// + /// Gets or sets the socket factory. + /// + /// + /// The socket factory. + /// + public virtual ISocketFactory SocketFactory { get; protected set; } + private List>> m_CommandLoaders = new List>>(); private Dictionary>> m_CommandContainer; @@ -175,9 +184,11 @@ public AppServerBase() /// Initializes a new instance of the class. /// /// The Receive filter factory. - public AppServerBase(IReceiveFilterFactory receiveFilterFactory) + /// + public AppServerBase(IReceiveFilterFactory receiveFilterFactory, ISocketFactory socketFactory = null) { this.ReceiveFilterFactory = receiveFilterFactory; + this.SocketFactory = socketFactory ?? new PassthroughSocketFactory(); } /// diff --git a/SocketBase/IAppServer.cs b/SocketBase/IAppServer.cs index 6b2dada2b..f28183439 100644 --- a/SocketBase/IAppServer.cs +++ b/SocketBase/IAppServer.cs @@ -12,6 +12,7 @@ using SuperSocket.SocketBase.Logging; using SuperSocket.SocketBase.Protocol; using SuperSocket.SocketBase.Provider; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketBase { @@ -42,6 +43,11 @@ public interface IAppServer : IWorkItem, ILoggerProvider /// object ReceiveFilterFactory { get; } + /// + /// Gets the socket factory. + /// + ISocketFactory SocketFactory { get; } + /// /// Gets the certificate of current server. /// diff --git a/SocketBase/ISocketSession.cs b/SocketBase/ISocketSession.cs index 6718c637d..1ab6c0aac 100644 --- a/SocketBase/ISocketSession.cs +++ b/SocketBase/ISocketSession.cs @@ -5,8 +5,8 @@ using System.IO; using System.Net; using System.Security.Authentication; -using System.Net.Sockets; using SuperSocket.SocketBase.Command; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketBase { @@ -104,7 +104,7 @@ public interface ISocketSession : ISessionBase /// /// Gets the client socket. /// - Socket Client { get; } + ISocket Client { get; } /// /// Gets the local listening endpoint. @@ -129,7 +129,6 @@ public interface ISocketSession : ISessionBase /// IAppSession AppSession { get; } - /// /// Gets the original receive buffer offset. /// diff --git a/SocketBase/Sockets/ISocket.cs b/SocketBase/Sockets/ISocket.cs new file mode 100644 index 000000000..48214e0e2 --- /dev/null +++ b/SocketBase/Sockets/ISocket.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// Socket interface + /// + public interface ISocket + { + /// + /// See + /// + bool Connected { get; } + + /// + /// See + /// + bool ExclusiveAddressUse { get; set; } + + /// + /// See + /// + EndPoint LocalEndPoint { get; } + + /// + /// See + /// + bool NoDelay { get; set; } + + /// + /// See + /// + int ReceiveBufferSize { get; set; } + + /// + /// See + /// + EndPoint RemoteEndPoint { get; } + + /// + /// See + /// + int SendBufferSize { get; set; } + + /// + /// See + /// + int SendTimeout { get; set; } + + /// + /// See + /// + /// + bool AcceptAsync(ISocketAsyncEventArgs e); + + /// + /// See + /// + /// + /// + /// + IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback callback, object state); + + /// + /// See + /// + /// + void Bind(EndPoint localEP); + + /// + /// See + /// + void Close(); + + /// + /// See + /// + /// + void Close(int timeout); + + /// + /// Creates a new stream + /// + /// + Stream CreateStream(); + + /// + /// See + /// + /// + void EndConnect(IAsyncResult asyncResult); + + /// + /// See + /// + /// + /// + /// + int IOControl(int ioControlCode, byte[] optionInValue, byte[] optionOutValue); + + /// + /// See + /// + /// + /// + /// + int IOControl(IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue); + + /// + /// See + /// + /// + void Listen(int backlog); + + /// + /// See + /// + /// + bool ReceiveAsync(ISocketAsyncEventArgs e); + + /// + /// See + /// + /// + bool ReceiveFromAsync(ISocketAsyncEventArgs e); + + /// + /// See + /// + /// + int Send(byte[] buffer); + + /// + /// See + /// + /// + /// + /// + /// + int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags); + + /// + /// See + /// + /// + /// + /// + /// + /// + int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode); + + /// + /// See + /// + /// + /// + /// + int Send(byte[] buffer, int size, SocketFlags socketFlags); + + /// + /// See + /// + /// + /// + int Send(byte[] buffer, SocketFlags socketFlags); + + /// + /// See + /// + /// + int Send(IList> buffers); + + /// + /// See + /// + /// + /// + int Send(IList> buffers, SocketFlags socketFlags); + + /// + /// See + /// + /// + /// + /// + int Send(IList> buffers, SocketFlags socketFlags, out SocketError socketError); + + /// + /// See + /// + /// + bool SendAsync(ISocketAsyncEventArgs e); + + /// + /// See + /// + /// + /// + /// + /// + /// + int SendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, EndPoint remoteEP); + + /// + /// See + /// + /// + bool SendToAsync(ISocketAsyncEventArgs e); + + /// + /// See + /// + /// + /// + /// + void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue); + + /// + /// See + /// + /// + /// + /// + void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, byte[] optionValue); + + /// + /// See + /// + /// + /// + /// + void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue); + + /// + /// See + /// + /// + /// + /// + void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue); + + /// + /// See + /// + /// + void Shutdown(SocketShutdown socketShutdown); + } +} \ No newline at end of file diff --git a/SocketBase/Sockets/ISocketAsyncEventArgs.cs b/SocketBase/Sockets/ISocketAsyncEventArgs.cs new file mode 100644 index 000000000..c8eadc236 --- /dev/null +++ b/SocketBase/Sockets/ISocketAsyncEventArgs.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// SocketAsyncEventArgs interface + /// + public abstract class ISocketAsyncEventArgs : EventArgs, IDisposable + { + /// + /// See + /// + public abstract event EventHandler Completed; + + /// + /// See + /// + public abstract ISocket AcceptSocket { get; set; } + + /// + /// See + /// + public abstract byte[] Buffer { get; } + + /// + /// See + /// + public abstract IList> BufferList { get; set; } + + /// + /// See + /// + public abstract int BytesTransferred { get; } + + /// + /// See + /// + public abstract Exception ConnectByNameError { get; } + + /// + /// See + /// + public abstract ISocket ConnectSocket { get; set; } + + /// + /// See + /// + public abstract int Count { get; } + + /// + /// See + /// + public abstract bool DisconnectReuseSocket { get; set; } + + /// + /// See + /// + public abstract SocketAsyncOperation LastOperation { get; } + + /// + /// See + /// + public abstract int Offset { get; } + + /// + /// See + /// + public abstract IPPacketInformation ReceiveMessageFromPacketInfo { get; } + + /// + /// See + /// + public abstract EndPoint RemoteEndPoint { get; set; } + + /// + /// See + /// + public abstract SendPacketsElement[] SendPacketsElements { get; set; } + + /// + /// See + /// + public abstract TransmitFileOptions SendPacketsFlags { get; set; } + + /// + /// See + /// + public abstract int SendPacketsSendSize { get; set; } + + /// + /// See + /// + public abstract SocketError SocketError { get; set; } + + /// + /// See + /// + public abstract SocketFlags SocketFlags { get; set; } + + /// + /// See + /// + public abstract object UserToken { get; set; } + + /// + /// See + /// + public abstract void SetBuffer(byte[] buffer, int offset, int count); + + /// + /// See + /// + public abstract void SetBuffer(int offset, int count); + + /// + public void Dispose() { } + } +} \ No newline at end of file diff --git a/Common/SocketEx.cs b/SocketBase/Sockets/ISocketEx.cs similarity index 83% rename from Common/SocketEx.cs rename to SocketBase/Sockets/ISocketEx.cs index 81f0b6281..01e835ea4 100644 --- a/Common/SocketEx.cs +++ b/SocketBase/Sockets/ISocketEx.cs @@ -1,18 +1,17 @@ -using System; using System.Net.Sockets; -namespace SuperSocket.Common +namespace SuperSocket.SocketBase.Sockets { /// /// Socket extension class /// - public static class SocketEx + public static class ISocketEx { /// /// Close the socket safely. /// /// The socket. - public static void SafeClose(this Socket socket) + public static void SafeClose(this ISocket socket) { if (socket == null) return; @@ -42,7 +41,7 @@ public static void SafeClose(this Socket socket) /// /// The client. /// The data. - public static void SendData(this Socket client, byte[] data) + public static void SendData(this ISocket client, byte[] data) { SendData(client, data, 0, data.Length); } @@ -54,7 +53,7 @@ public static void SendData(this Socket client, byte[] data) /// The data. /// The offset. /// The length. - public static void SendData(this Socket client, byte[] data, int offset, int length) + public static void SendData(this ISocket client, byte[] data, int offset, int length) { int sent = 0; int thisSent = 0; diff --git a/SocketBase/Sockets/ISocketFactory.cs b/SocketBase/Sockets/ISocketFactory.cs new file mode 100644 index 000000000..226208589 --- /dev/null +++ b/SocketBase/Sockets/ISocketFactory.cs @@ -0,0 +1,24 @@ +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// SocketFactory interface + /// + public interface ISocketFactory + { + /// + /// Creates a new + /// + /// + /// + /// + ISocket Create(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType); + + /// + /// Creates a new + /// + /// + ISocketAsyncEventArgs CreateSocketAsyncEventArgs(); + } +} \ No newline at end of file diff --git a/SocketBase/Sockets/PassthroughSocket.cs b/SocketBase/Sockets/PassthroughSocket.cs new file mode 100644 index 000000000..43c255e94 --- /dev/null +++ b/SocketBase/Sockets/PassthroughSocket.cs @@ -0,0 +1,310 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// Passthrough Socket + /// + public class PassthroughSocket : ISocket + { + private readonly Socket _socket; + + /// + public bool Connected + { + get + { + return _socket.Connected; + } + } + + /// + public bool ExclusiveAddressUse + { + get + { + return _socket.ExclusiveAddressUse; + } + + set + { + _socket.ExclusiveAddressUse = value; + } + } + + /// + public EndPoint LocalEndPoint + { + get + { + return _socket.LocalEndPoint; + } + } + + /// + public bool NoDelay + { + get + { + return _socket.NoDelay; + } + + set + { + _socket.NoDelay = value; + } + } + + /// + public int ReceiveBufferSize + { + get + { + return _socket.ReceiveBufferSize; + } + + set + { + _socket.ReceiveBufferSize = value; + } + } + + /// + public EndPoint RemoteEndPoint + { + get + { + return _socket.RemoteEndPoint; + } + } + + /// + public int SendBufferSize + { + get + { + return _socket.SendBufferSize; + } + + set + { + _socket.SendBufferSize = value; + } + } + + /// + public int SendTimeout + { + get + { + return _socket.SendTimeout; + } + + set + { + _socket.SendTimeout = value; + } + } + + /// + /// Instantiates a + /// + /// + public PassthroughSocket(Socket socket) + { + _socket = socket; + } + + /// + /// Instantiates a + /// + /// + public PassthroughSocket(SocketInformation socketInformation) + { + _socket = new Socket(socketInformation); + } + + /// + /// Instantiates a + /// + /// + /// + /// + public PassthroughSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) + { + _socket = new Socket(addressFamily, socketType, protocolType); + } + + /// + public bool AcceptAsync(ISocketAsyncEventArgs e) + { + return _socket.AcceptAsync(((PassthroughSocketAsyncEventArgs)e).SocketAsyncEventArgs); + } + + /// + public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback callback, object state) + { + return _socket.BeginConnect(remoteEP, callback, state); + } + + /// + public void Bind(EndPoint localEP) + { + _socket.Bind(localEP); + } + + /// + public void Close() + { + _socket.Close(); + } + + /// + public void Close(int timeout) + { + _socket.Close(timeout); + } + + /// + public Stream CreateStream() + { + return new NetworkStream(_socket); + } + + /// + public void EndConnect(IAsyncResult asyncResult) + { + _socket.EndConnect(asyncResult); + } + + /// + public int IOControl(int ioControlCode, byte[] optionInValue, byte[] optionOutValue) + { + return _socket.IOControl(ioControlCode, optionInValue, optionOutValue); + } + + /// + public int IOControl(IOControlCode ioControlCode, byte[] optionInValue, byte[] optionOutValue) + { + return _socket.IOControl(ioControlCode, optionInValue, optionOutValue); + } + + /// + public void Listen(int backlog) + { + _socket.Listen(backlog); + } + + /// + public bool ReceiveAsync(ISocketAsyncEventArgs e) + { + return _socket.ReceiveAsync(((PassthroughSocketAsyncEventArgs)e).SocketAsyncEventArgs); + } + + /// + public bool ReceiveFromAsync(ISocketAsyncEventArgs e) + { + return _socket.ReceiveFromAsync(((PassthroughSocketAsyncEventArgs)e).SocketAsyncEventArgs); + } + + /// + public int Send(byte[] buffer) + { + return _socket.Send(buffer); + } + + /// + public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags) + { + return _socket.Send(buffer, offset, size, socketFlags); + } + + /// + public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode) + { + return _socket.Send(buffer, offset, size, socketFlags, out errorCode); + } + + /// + public int Send(byte[] buffer, int size, SocketFlags socketFlags) + { + return _socket.Send(buffer, size, socketFlags); + } + + /// + public int Send(byte[] buffer, SocketFlags socketFlags) + { + return _socket.Send(buffer, socketFlags); + } + + /// + public int Send(IList> buffers) + { + return _socket.Send(buffers); + } + + /// + public int Send(IList> buffers, SocketFlags socketFlags) + { + return _socket.Send(buffers, socketFlags); + } + + /// + public int Send(IList> buffers, SocketFlags socketFlags, out SocketError socketError) + { + return _socket.Send(buffers, socketFlags, out socketError); + } + + /// + public bool SendAsync(ISocketAsyncEventArgs e) + { + return _socket.SendAsync(((PassthroughSocketAsyncEventArgs)e).SocketAsyncEventArgs); + } + + /// + public int SendTo(byte[] buffer, int offset, int size, SocketFlags socketFlags, EndPoint remoteEP) + { + return _socket.SendTo(buffer, offset, size, socketFlags, remoteEP); + } + + /// + public bool SendToAsync(ISocketAsyncEventArgs e) + { + return _socket.SendToAsync(((PassthroughSocketAsyncEventArgs)e).SocketAsyncEventArgs); + } + + /// + public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, bool optionValue) + { + _socket.SetSocketOption(optionLevel, optionName, optionValue); + } + + /// + public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, byte[] optionValue) + { + _socket.SetSocketOption(optionLevel, optionName, optionValue); + } + + /// + public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue) + { + _socket.SetSocketOption(optionLevel, optionName, optionValue); + } + + /// + public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, object optionValue) + { + _socket.SetSocketOption(optionLevel, optionName, optionValue); + } + + /// + public void Shutdown(SocketShutdown socketShutdown) + { + _socket.Shutdown(socketShutdown); + } + } +} \ No newline at end of file diff --git a/SocketBase/Sockets/PassthroughSocketAsyncEventArgs.cs b/SocketBase/Sockets/PassthroughSocketAsyncEventArgs.cs new file mode 100644 index 000000000..d114ed5ff --- /dev/null +++ b/SocketBase/Sockets/PassthroughSocketAsyncEventArgs.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// Passthrough SocketAsyncEventArgs + /// + public class PassthroughSocketAsyncEventArgs : ISocketAsyncEventArgs + { + private ISocket _acceptSocket; + private readonly SocketAsyncEventArgs _socketAsyncEventArgs; + + /// + /// SocketAsyncEventArgs + /// + public SocketAsyncEventArgs SocketAsyncEventArgs + { + get + { + return _socketAsyncEventArgs; + } + } + + /// + /// See + /// + public override event EventHandler Completed; + + /// + /// See + /// + public override ISocket AcceptSocket { + get + { + return _acceptSocket; + } + set + { + if (null == value) + { + _acceptSocket = null; + _socketAsyncEventArgs.AcceptSocket = null; + } + else + { + _acceptSocket = value; + } + } + } + + /// + /// See + /// + public override byte[] Buffer { + get + { + return _socketAsyncEventArgs.Buffer; + } + } + + /// + /// See + /// + public override IList> BufferList + { + get + { + return _socketAsyncEventArgs.BufferList; + } + + set + { + _socketAsyncEventArgs.BufferList = value; + } + } + + /// + /// See + /// + public override int BytesTransferred + { + get + { + return _socketAsyncEventArgs.BytesTransferred; + } + } + + /// + /// See + /// + public override Exception ConnectByNameError + { + get + { + return _socketAsyncEventArgs.ConnectByNameError; + } + } + + /// + /// See + /// + public override ISocket ConnectSocket { get; set; } + + /// + /// See + /// + public override int Count + { + get + { + return _socketAsyncEventArgs.Count; + } + } + + /// + /// See + /// + public override bool DisconnectReuseSocket + { + get + { + return _socketAsyncEventArgs.DisconnectReuseSocket; + } + + set + { + _socketAsyncEventArgs.DisconnectReuseSocket = value; + } + } + + /// + /// See + /// + public override SocketAsyncOperation LastOperation + { + get + { + return _socketAsyncEventArgs.LastOperation; + } + } + + /// + /// See + /// + public override int Offset + { + get + { + return _socketAsyncEventArgs.Offset; + } + } + + /// + /// See + /// + public override IPPacketInformation ReceiveMessageFromPacketInfo + { + get + { + return _socketAsyncEventArgs.ReceiveMessageFromPacketInfo; + } + } + + /// + /// See + /// + public override EndPoint RemoteEndPoint + { + get + { + return _socketAsyncEventArgs.RemoteEndPoint; + } + + set + { + _socketAsyncEventArgs.RemoteEndPoint = value; + } + } + + /// + /// See + /// + public override SendPacketsElement[] SendPacketsElements + { + get + { + return _socketAsyncEventArgs.SendPacketsElements; + } + + set + { + _socketAsyncEventArgs.SendPacketsElements = value; + } + } + + /// + /// See + /// + public override TransmitFileOptions SendPacketsFlags + { + get + { + return _socketAsyncEventArgs.SendPacketsFlags; + } + + set + { + _socketAsyncEventArgs.SendPacketsFlags = value; + } + } + + /// + /// See + /// + public override int SendPacketsSendSize + { + get + { + return _socketAsyncEventArgs.SendPacketsSendSize; + } + + set + { + _socketAsyncEventArgs.SendPacketsSendSize = value; + } + } + + /// + /// See + /// + public override SocketError SocketError + { + get + { + return _socketAsyncEventArgs.SocketError; + } + + set + { + _socketAsyncEventArgs.SocketError = value; + } + } + + /// + /// See + /// + public override SocketFlags SocketFlags + { + get + { + return _socketAsyncEventArgs.SocketFlags; + } + + set + { + _socketAsyncEventArgs.SocketFlags = value; + } + } + + /// + /// See + /// + public override object UserToken + { + get + { + return _socketAsyncEventArgs.UserToken; + } + + set + { + _socketAsyncEventArgs.UserToken = value; + } + } + + /// + /// Instantiates a adapter + /// + public PassthroughSocketAsyncEventArgs() + { + _socketAsyncEventArgs = new SocketAsyncEventArgs(); + _socketAsyncEventArgs.Completed += (sender, args) => + { + this.Map(args); + + this.OnPassthroughSocketAsyncEventArgsCompleted(); + }; + } + + /// + /// See + /// + /// + /// + /// + public override void SetBuffer(byte[] buffer, int offset, int count) + { + _socketAsyncEventArgs.SetBuffer(buffer, offset, count); + } + + /// + /// See + /// + /// + /// + public override void SetBuffer(int offset, int count) + { + _socketAsyncEventArgs.SetBuffer(offset, count); + } + + /// + /// Maps a + /// + /// + public void Map(SocketAsyncEventArgs e) + { + this.AcceptSocket = new PassthroughSocket(e.AcceptSocket); + this.ConnectSocket = new PassthroughSocket(e.ConnectSocket); + } + + /// + /// Fires Completed event + /// + public void OnPassthroughSocketAsyncEventArgsCompleted() + { + var handler = Completed; + if (null != handler) + { + handler(this, this); + } + } + + /// + public new void Dispose() + { + base.Dispose(); + } + } +} \ No newline at end of file diff --git a/SocketBase/Sockets/PassthroughSocketFactory.cs b/SocketBase/Sockets/PassthroughSocketFactory.cs new file mode 100644 index 000000000..58506f034 --- /dev/null +++ b/SocketBase/Sockets/PassthroughSocketFactory.cs @@ -0,0 +1,22 @@ +using System.Net.Sockets; + +namespace SuperSocket.SocketBase.Sockets +{ + /// + /// Passthrough Socket Factory + /// + public class PassthroughSocketFactory : ISocketFactory + { + /// + public ISocket Create(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) + { + return new PassthroughSocket(addressFamily, socketType, protocolType); + } + + /// + public ISocketAsyncEventArgs CreateSocketAsyncEventArgs() + { + return new PassthroughSocketAsyncEventArgs(); + } + } +} \ No newline at end of file diff --git a/SocketBase/SuperSocket.SocketBase.Net35.csproj b/SocketBase/SuperSocket.SocketBase.Net35.csproj index ff4ca15f0..84ec28871 100644 --- a/SocketBase/SuperSocket.SocketBase.Net35.csproj +++ b/SocketBase/SuperSocket.SocketBase.Net35.csproj @@ -99,6 +99,9 @@ + + + @@ -147,7 +150,11 @@ + + + + diff --git a/SocketBase/SuperSocket.SocketBase.Net40.csproj b/SocketBase/SuperSocket.SocketBase.Net40.csproj index 3d2260ef0..3cd35c53d 100644 --- a/SocketBase/SuperSocket.SocketBase.Net40.csproj +++ b/SocketBase/SuperSocket.SocketBase.Net40.csproj @@ -96,6 +96,9 @@ + + + @@ -155,11 +158,15 @@ + + + + diff --git a/SocketBase/SuperSocket.SocketBase.Net45.csproj b/SocketBase/SuperSocket.SocketBase.Net45.csproj index d70d2c699..47efb8479 100644 --- a/SocketBase/SuperSocket.SocketBase.Net45.csproj +++ b/SocketBase/SuperSocket.SocketBase.Net45.csproj @@ -100,6 +100,9 @@ + + + @@ -164,11 +167,15 @@ + + + + diff --git a/SocketEngine/AsyncSocket/SocketAsyncEventArgsProxy.cs b/SocketEngine/AsyncSocket/SocketAsyncEventArgsProxy.cs index c675ec1e0..ca6f544a6 100644 --- a/SocketEngine/AsyncSocket/SocketAsyncEventArgsProxy.cs +++ b/SocketEngine/AsyncSocket/SocketAsyncEventArgsProxy.cs @@ -5,12 +5,13 @@ using System.Text; using SuperSocket.Common; using SuperSocket.SocketBase; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine.AsyncSocket { class SocketAsyncEventArgsProxy { - public SocketAsyncEventArgs SocketEventArgs { get; private set; } + public ISocketAsyncEventArgs SocketEventArgs { get; private set; } public int OrigOffset { get; private set; } @@ -21,21 +22,21 @@ private SocketAsyncEventArgsProxy() } - public SocketAsyncEventArgsProxy(SocketAsyncEventArgs socketEventArgs) + public SocketAsyncEventArgsProxy(ISocketAsyncEventArgs socketEventArgs) : this(socketEventArgs, true) { } - public SocketAsyncEventArgsProxy(SocketAsyncEventArgs socketEventArgs, bool isRecyclable) + public SocketAsyncEventArgsProxy(ISocketAsyncEventArgs socketEventArgs, bool isRecyclable) { SocketEventArgs = socketEventArgs; OrigOffset = socketEventArgs.Offset; - SocketEventArgs.Completed += new EventHandler(SocketEventArgs_Completed); + SocketEventArgs.Completed += new EventHandler(SocketEventArgs_Completed); IsRecyclable = isRecyclable; } - static void SocketEventArgs_Completed(object sender, SocketAsyncEventArgs e) + static void SocketEventArgs_Completed(object sender, ISocketAsyncEventArgs e) { var socketSession = e.UserToken as IAsyncSocketSession; diff --git a/SocketEngine/AsyncSocketServer.cs b/SocketEngine/AsyncSocketServer.cs index a87a10fd0..a16d648d8 100644 --- a/SocketEngine/AsyncSocketServer.cs +++ b/SocketEngine/AsyncSocketServer.cs @@ -13,6 +13,7 @@ using SuperSocket.SocketBase; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; using SuperSocket.SocketEngine.AsyncSocket; namespace SuperSocket.SocketEngine @@ -51,15 +52,17 @@ public override bool Start() } // preallocate pool of SocketAsyncEventArgs objects - SocketAsyncEventArgs socketEventArg; + ISocketAsyncEventArgs socketEventArg; var socketArgsProxyList = new List(AppServer.Config.MaxConnectionNumber); for (int i = 0; i < AppServer.Config.MaxConnectionNumber; i++) { //Pre-allocate a set of reusable SocketAsyncEventArgs - socketEventArg = new SocketAsyncEventArgs(); - m_BufferManager.SetBuffer(socketEventArg); + socketEventArg = AppServer.SocketFactory.CreateSocketAsyncEventArgs(); + var bufferInfo = m_BufferManager.SetBuffer(); + if (bufferInfo.Item1) + socketEventArg.SetBuffer(m_BufferManager.Buffer, bufferInfo.Item2, m_BufferManager.BufferSize); socketArgsProxyList.Add(new SocketAsyncEventArgsProxy(socketEventArg)); } @@ -79,7 +82,7 @@ public override bool Start() } } - protected override void OnNewClientAccepted(ISocketListener listener, Socket client, object state) + protected override void OnNewClientAccepted(ISocketListener listener, ISocket client, object state) { if (IsStopped) return; @@ -87,7 +90,7 @@ protected override void OnNewClientAccepted(ISocketListener listener, Socket cli ProcessNewClient(client, listener.Info.Security); } - private IAppSession ProcessNewClient(Socket client, SslProtocols security) + private IAppSession ProcessNewClient(ISocket client, SslProtocols security) { //Get the socket for the accepted client connection and put it into the //ReadEventArg object user token @@ -104,7 +107,7 @@ private IAppSession ProcessNewClient(Socket client, SslProtocols security) ISocketSession socketSession; if (security == SslProtocols.None) - socketSession = new AsyncSocketSession(client, socketEventArgsProxy); + socketSession = new AsyncSocketSession(client, socketEventArgsProxy, this.AppServer.SocketFactory); else socketSession = new AsyncStreamSocketSession(client, security, socketEventArgsProxy); @@ -171,7 +174,7 @@ public override void ResetSessionSecurity(IAppSession session, SslProtocols secu var socketAsyncProxy = ((IAsyncSocketSessionBase)session.SocketSession).SocketAsyncProxy; if (security == SslProtocols.None) - socketSession = new AsyncSocketSession(session.SocketSession.Client, socketAsyncProxy, true); + socketSession = new AsyncSocketSession(session.SocketSession.Client, socketAsyncProxy, true, this.AppServer.SocketFactory); else socketSession = new AsyncStreamSocketSession(session.SocketSession.Client, security, socketAsyncProxy, true); @@ -239,9 +242,9 @@ class ActiveConnectState { public TaskCompletionSource TaskSource { get; private set; } - public Socket Socket { get; private set; } + public ISocket Socket { get; private set; } - public ActiveConnectState(TaskCompletionSource taskSource, Socket socket) + public ActiveConnectState(TaskCompletionSource taskSource, ISocket socket) { TaskSource = taskSource; Socket = socket; @@ -256,7 +259,7 @@ Task IActiveConnector.ActiveConnect(EndPoint targetEndPoint Task IActiveConnector.ActiveConnect(EndPoint targetEndPoint, EndPoint localEndPoint) { var taskSource = new TaskCompletionSource(); - var socket = new Socket(targetEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + var socket = this.AppServer.SocketFactory.Create(targetEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (localEndPoint != null) { diff --git a/SocketEngine/AsyncSocketSession.cs b/SocketEngine/AsyncSocketSession.cs index 3568fb22b..579733508 100644 --- a/SocketEngine/AsyncSocketSession.cs +++ b/SocketEngine/AsyncSocketSession.cs @@ -11,6 +11,7 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Logging; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; using SuperSocket.SocketEngine.AsyncSocket; namespace SuperSocket.SocketEngine @@ -19,19 +20,21 @@ class AsyncSocketSession : SocketSession, IAsyncSocketSession { private bool m_IsReset; - private SocketAsyncEventArgs m_SocketEventArgSend; + private ISocketAsyncEventArgs m_SocketEventArgSend; + private ISocketFactory m_SocketFactory; - public AsyncSocketSession(Socket client, SocketAsyncEventArgsProxy socketAsyncProxy) - : this(client, socketAsyncProxy, false) + public AsyncSocketSession(ISocket client, SocketAsyncEventArgsProxy socketAsyncProxy, ISocketFactory socketFactory) + : this(client, socketAsyncProxy, false, socketFactory) { } - public AsyncSocketSession(Socket client, SocketAsyncEventArgsProxy socketAsyncProxy, bool isReset) + public AsyncSocketSession(ISocket client, SocketAsyncEventArgsProxy socketAsyncProxy, bool isReset, ISocketFactory socketFactory) : base(client) { SocketAsyncProxy = socketAsyncProxy; m_IsReset = isReset; + m_SocketFactory = socketFactory; } ILog ILoggerProvider.Logger @@ -49,8 +52,8 @@ public override void Initialize(IAppSession appSession) if (!SyncSend) { //Initialize SocketAsyncEventArgs for sending - m_SocketEventArgSend = new SocketAsyncEventArgs(); - m_SocketEventArgSend.Completed += new EventHandler(OnSendingCompleted); + m_SocketEventArgSend = m_SocketFactory.CreateSocketAsyncEventArgs(); + m_SocketEventArgSend.Completed += new EventHandler(OnSendingCompleted); } } @@ -62,7 +65,7 @@ public override void Start() StartSession(); } - bool ProcessCompleted(SocketAsyncEventArgs e) + bool ProcessCompleted(ISocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { @@ -79,7 +82,7 @@ bool ProcessCompleted(SocketAsyncEventArgs e) return false; } - void OnSendingCompleted(object sender, SocketAsyncEventArgs e) + void OnSendingCompleted(object sender, ISocketAsyncEventArgs e) { var queue = e.UserToken as SendingQueue; @@ -105,7 +108,7 @@ void OnSendingCompleted(object sender, SocketAsyncEventArgs e) base.OnSendingCompleted(queue); } - private void ClearPrevSendState(SocketAsyncEventArgs e) + private void ClearPrevSendState(ISocketAsyncEventArgs e) { e.UserToken = null; @@ -120,12 +123,12 @@ private void ClearPrevSendState(SocketAsyncEventArgs e) } } - private void StartReceive(SocketAsyncEventArgs e) + private void StartReceive(ISocketAsyncEventArgs e) { StartReceive(e, 0); } - private void StartReceive(SocketAsyncEventArgs e, int offsetDelta) + private void StartReceive(ISocketAsyncEventArgs e, int offsetDelta) { bool willRaiseEvent = false; @@ -223,7 +226,7 @@ protected override void SendAsync(SendingQueue queue) public SocketAsyncEventArgsProxy SocketAsyncProxy { get; private set; } - public void ProcessReceive(SocketAsyncEventArgs e) + public void ProcessReceive(ISocketAsyncEventArgs e) { if (!ProcessCompleted(e)) { diff --git a/SocketEngine/AsyncStreamSocketSession.cs b/SocketEngine/AsyncStreamSocketSession.cs index af430d876..b7198d299 100644 --- a/SocketEngine/AsyncStreamSocketSession.cs +++ b/SocketEngine/AsyncStreamSocketSession.cs @@ -14,6 +14,7 @@ using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Logging; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; using SuperSocket.SocketEngine.AsyncSocket; namespace SuperSocket.SocketEngine @@ -59,13 +60,13 @@ class AsyncStreamSocketSession : SocketSession, IAsyncSocketSessionBase, INegoti private bool m_IsReset; - public AsyncStreamSocketSession(Socket client, SslProtocols security, SocketAsyncEventArgsProxy socketAsyncProxy) + public AsyncStreamSocketSession(ISocket client, SslProtocols security, SocketAsyncEventArgsProxy socketAsyncProxy) : this(client, security, socketAsyncProxy, false) { } - public AsyncStreamSocketSession(Socket client, SslProtocols security, SocketAsyncEventArgsProxy socketAsyncProxy, bool isReset) + public AsyncStreamSocketSession(ISocket client, SslProtocols security, SocketAsyncEventArgsProxy socketAsyncProxy, bool isReset) : base(client) { SecureProtocol = security; @@ -171,10 +172,10 @@ private SslStream CreateSslStream(ICertificateConfig certConfig) { //Enable client certificate function only if ClientCertificateRequired is true in the configuration if(!certConfig.ClientCertificateRequired) - return new SslStream(new NetworkStream(Client), false); + return new SslStream(Client.CreateStream(), false); //ToDo: //Subscribe the client validation callback - return new SslStream(new NetworkStream(Client), false, ValidateClientCertificate); + return new SslStream(Client.CreateStream(), false, ValidateClientCertificate); } private bool ValidateClientCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) @@ -201,7 +202,7 @@ private IAsyncResult BeginInitStream(AsyncCallback asyncCallback) switch (secureProtocol) { case (SslProtocols.None): - m_Stream = new NetworkStream(Client); + m_Stream = Client.CreateStream(); break; case (SslProtocols.Default): case (SslProtocols.Tls): diff --git a/SocketEngine/IAsyncSocketSession.cs b/SocketEngine/IAsyncSocketSession.cs index 9fd1cf2a1..34ec0e476 100644 --- a/SocketEngine/IAsyncSocketSession.cs +++ b/SocketEngine/IAsyncSocketSession.cs @@ -6,6 +6,7 @@ using SuperSocket.Common; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Logging; +using SuperSocket.SocketBase.Sockets; using SuperSocket.SocketEngine.AsyncSocket; namespace SuperSocket.SocketEngine @@ -14,11 +15,11 @@ interface IAsyncSocketSessionBase : ILoggerProvider { SocketAsyncEventArgsProxy SocketAsyncProxy { get; } - Socket Client { get; } + ISocket Client { get; } } interface IAsyncSocketSession : IAsyncSocketSessionBase { - void ProcessReceive(SocketAsyncEventArgs e); + void ProcessReceive(ISocketAsyncEventArgs e); } } diff --git a/SocketEngine/ISocketListener.cs b/SocketEngine/ISocketListener.cs index e1cec3d74..bb3955494 100644 --- a/SocketEngine/ISocketListener.cs +++ b/SocketEngine/ISocketListener.cs @@ -6,12 +6,13 @@ using SuperSocket.SocketBase.Config; using System.Net.Sockets; using System.Net; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { delegate void ErrorHandler(ISocketListener listener, Exception e); - delegate void NewClientAcceptHandler(ISocketListener listener, Socket client, object state); + delegate void NewClientAcceptHandler(ISocketListener listener, ISocket client, object state); /// /// The interface for socket listener diff --git a/SocketEngine/SocketListenerBase.cs b/SocketEngine/SocketListenerBase.cs index da85919f1..8bbaf0a38 100644 --- a/SocketEngine/SocketListenerBase.cs +++ b/SocketEngine/SocketListenerBase.cs @@ -6,21 +6,24 @@ using System.Text; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { abstract class SocketListenerBase : ISocketListener { public ListenerInfo Info { get; private set; } + public ISocketFactory SocketFactory { get; private set; } public IPEndPoint EndPoint { get { return Info.EndPoint; } } - protected SocketListenerBase(ListenerInfo info) + protected SocketListenerBase(ListenerInfo info, ISocketFactory socketFactory) { Info = info; + SocketFactory = socketFactory ?? new PassthroughSocketFactory(); } /// @@ -49,7 +52,7 @@ protected void OnError(string errorMessage) OnError(new Exception(errorMessage)); } - protected virtual void OnNewClientAccepted(Socket socket, object state) + protected virtual void OnNewClientAccepted(ISocket socket, object state) { var handler = NewClientAccepted; @@ -57,7 +60,7 @@ protected virtual void OnNewClientAccepted(Socket socket, object state) handler(this, socket, state); } - protected void OnNewClientAcceptedAsync(Socket socket, object state) + protected void OnNewClientAcceptedAsync(ISocket socket, object state) { var handler = NewClientAccepted; diff --git a/SocketEngine/SocketServerBase.cs b/SocketEngine/SocketServerBase.cs index 931e0dc51..a5db1ae9a 100644 --- a/SocketEngine/SocketServerBase.cs +++ b/SocketEngine/SocketServerBase.cs @@ -14,6 +14,7 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Logging; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { @@ -106,7 +107,7 @@ public virtual bool Start() return true; } - protected abstract void OnNewClientAccepted(ISocketListener listener, Socket client, object state); + protected abstract void OnNewClientAccepted(ISocketListener listener, ISocket client, object state); void OnListenerError(ISocketListener listener, Exception e) { diff --git a/SocketEngine/SocketSession.cs b/SocketEngine/SocketSession.cs index 9fd4818c0..fa22d3ead 100644 --- a/SocketEngine/SocketSession.cs +++ b/SocketEngine/SocketSession.cs @@ -13,6 +13,7 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { @@ -113,7 +114,7 @@ private bool CheckState(int stateValue) private ISmartPool m_SendingQueuePool; - public SocketSession(Socket client) + public SocketSession(ISocket client) : this(Guid.NewGuid().ToString()) { if (client == null) @@ -305,7 +306,7 @@ private void StartSend(SendingQueue queue, int sendingTrackID, bool initial) } } - Socket client; + ISocket client; if (IsInClosingOrClosed && TryValidateClosedBySocket(out client)) { @@ -378,7 +379,7 @@ protected virtual void OnSendingCompleted(SendingQueue queue) if (IsInClosingOrClosed) { - Socket client; + ISocket client; //has data is being sent and the socket isn't closed if (newQueue.Count > 0 && !TryValidateClosedBySocket(out client)) @@ -410,15 +411,15 @@ protected virtual void OnSendingCompleted(SendingQueue queue) public Stream GetUnderlyStream() { - return new NetworkStream(Client); + return Client.CreateStream(); } - private Socket m_Client; + private ISocket m_Client; /// /// Gets or sets the client. /// /// The client. - public Socket Client + public ISocket Client { get { return m_Client; } } @@ -451,7 +452,7 @@ protected bool IsClosed /// The secure protocol. public SslProtocols SecureProtocol { get; set; } - protected virtual bool TryValidateClosedBySocket(out Socket socket) + protected virtual bool TryValidateClosedBySocket(out ISocket socket) { socket = m_Client; //Already closed/closing @@ -464,7 +465,7 @@ public virtual void Close(CloseReason reason) if (!TryAddStateFlag(SocketState.InClosing)) return; - Socket client; + ISocket client; //No need to clean the socket instance if (TryValidateClosedBySocket(out client)) @@ -485,7 +486,7 @@ public virtual void Close(CloseReason reason) OnClosed(reason); } - private void InternalClose(Socket client, CloseReason reason, bool setCloseReason) + private void InternalClose(ISocket client, CloseReason reason, bool setCloseReason) { if (Interlocked.CompareExchange(ref m_Client, null, client) == client) { @@ -589,7 +590,7 @@ private void ValidateClosed(CloseReason closeReason, bool forceClose, bool forSe // so we check if the socket instance is alive now if (forSend) { - Socket client; + ISocket client; if (!TryValidateClosedBySocket(out client)) { diff --git a/SocketEngine/TcpAsyncSocketListener.cs b/SocketEngine/TcpAsyncSocketListener.cs index 033934f66..9fe685c60 100644 --- a/SocketEngine/TcpAsyncSocketListener.cs +++ b/SocketEngine/TcpAsyncSocketListener.cs @@ -7,6 +7,7 @@ using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; using SuperSocket.SocketBase.Logging; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { @@ -17,12 +18,12 @@ class TcpAsyncSocketListener : SocketListenerBase { private int m_ListenBackLog; - private Socket m_ListenSocket; + private ISocket m_ListenSocket; - private SocketAsyncEventArgs m_AcceptSAE; + private ISocketAsyncEventArgs m_AcceptSAE; - public TcpAsyncSocketListener(ListenerInfo info) - : base(info) + public TcpAsyncSocketListener(ListenerInfo info, ISocketFactory socketFactory) + : base(info, socketFactory) { m_ListenBackLog = info.BackLog; } @@ -34,7 +35,7 @@ public TcpAsyncSocketListener(ListenerInfo info) /// public override bool Start(IServerConfig config) { - m_ListenSocket = new Socket(this.Info.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + m_ListenSocket = this.SocketFactory.Create(this.Info.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { @@ -43,14 +44,14 @@ public override bool Start(IServerConfig config) m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true); - - SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs(); + + var acceptEventArg = this.SocketFactory.CreateSocketAsyncEventArgs(); m_AcceptSAE = acceptEventArg; - acceptEventArg.Completed += new EventHandler(acceptEventArg_Completed); + acceptEventArg.Completed += new EventHandler(acceptEventArg_Completed); if (!m_ListenSocket.AcceptAsync(acceptEventArg)) ProcessAccept(acceptEventArg); - + return true; } @@ -62,14 +63,14 @@ public override bool Start(IServerConfig config) } - void acceptEventArg_Completed(object sender, SocketAsyncEventArgs e) + void acceptEventArg_Completed(object sender, ISocketAsyncEventArgs e) { ProcessAccept(e); } - void ProcessAccept(SocketAsyncEventArgs e) + void ProcessAccept(ISocketAsyncEventArgs e) { - Socket socket = null; + ISocket socket = null; if (e.SocketError != SocketError.Success) { @@ -132,7 +133,7 @@ public override void Stop() if (m_ListenSocket == null) return; - m_AcceptSAE.Completed -= new EventHandler(acceptEventArg_Completed); + m_AcceptSAE.Completed -= new EventHandler(acceptEventArg_Completed); m_AcceptSAE.Dispose(); m_AcceptSAE = null; diff --git a/SocketEngine/TcpSocketServerBase.cs b/SocketEngine/TcpSocketServerBase.cs index 47c77bad8..6413ebbbd 100644 --- a/SocketEngine/TcpSocketServerBase.cs +++ b/SocketEngine/TcpSocketServerBase.cs @@ -10,6 +10,7 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Logging; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { @@ -41,7 +42,7 @@ public TcpSocketServerBase(IAppServer appServer, ListenerInfo[] listeners) m_SendBufferSize = config.SendBufferSize; } - protected IAppSession CreateSession(Socket client, ISocketSession session) + protected IAppSession CreateSession(ISocket client, ISocketSession session) { if (m_SendTimeOut > 0) client.SendTimeout = m_SendTimeOut; @@ -65,7 +66,7 @@ protected IAppSession CreateSession(Socket client, ISocketSession session) protected override ISocketListener CreateListener(ListenerInfo listenerInfo) { - return new TcpAsyncSocketListener(listenerInfo); + return new TcpAsyncSocketListener(listenerInfo, this.AppServer.SocketFactory); } } } diff --git a/SocketEngine/UdpSocketListener.cs b/SocketEngine/UdpSocketListener.cs index 44850f946..c8725729a 100644 --- a/SocketEngine/UdpSocketListener.cs +++ b/SocketEngine/UdpSocketListener.cs @@ -7,17 +7,18 @@ using SuperSocket.Common; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { class UdpSocketListener : SocketListenerBase { - private Socket m_ListenSocket; + private ISocket m_ListenSocket; - private SocketAsyncEventArgs m_ReceiveSAE; + private ISocketAsyncEventArgs m_ReceiveSAE; - public UdpSocketListener(ListenerInfo info) - : base(info) + public UdpSocketListener(ListenerInfo info, ISocketFactory socketFactory) + : base(info, socketFactory) { } @@ -31,7 +32,7 @@ public override bool Start(IServerConfig config) { try { - m_ListenSocket = new Socket(this.EndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + m_ListenSocket = this.SocketFactory.Create(this.EndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); m_ListenSocket.Bind(this.EndPoint); @@ -47,10 +48,10 @@ public override bool Start(IServerConfig config) m_ListenSocket.IOControl((int)SIO_UDP_CONNRESET, optionInValue, optionOutValue); } - var eventArgs = new SocketAsyncEventArgs(); + var eventArgs = this.SocketFactory.CreateSocketAsyncEventArgs(); m_ReceiveSAE = eventArgs; - eventArgs.Completed += new EventHandler(eventArgs_Completed); + eventArgs.Completed += new EventHandler(eventArgs_Completed); eventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); int receiveBufferSize = config.ReceiveBufferSize <= 0 ? 2048 : config.ReceiveBufferSize; @@ -68,7 +69,7 @@ public override bool Start(IServerConfig config) } } - void eventArgs_Completed(object sender, SocketAsyncEventArgs e) + void eventArgs_Completed(object sender, ISocketAsyncEventArgs e) { if (e.SocketError != SocketError.Success) { @@ -113,7 +114,7 @@ public override void Stop() if (m_ListenSocket == null) return; - m_ReceiveSAE.Completed -= new EventHandler(eventArgs_Completed); + m_ReceiveSAE.Completed -= new EventHandler(eventArgs_Completed); m_ReceiveSAE.Dispose(); m_ReceiveSAE = null; diff --git a/SocketEngine/UdpSocketServer.cs b/SocketEngine/UdpSocketServer.cs index 864837d48..9449cd97d 100644 --- a/SocketEngine/UdpSocketServer.cs +++ b/SocketEngine/UdpSocketServer.cs @@ -10,6 +10,7 @@ using SuperSocket.SocketBase; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; +using SuperSocket.SocketBase.Sockets; using SuperSocket.SocketEngine.AsyncSocket; namespace SuperSocket.SocketEngine @@ -53,7 +54,7 @@ public UdpSocketServer(IAppServer appServer, ListenerInfo[] listeners) /// The listener. /// The client. /// The state. - protected override void OnNewClientAccepted(ISocketListener listener, Socket client, object state) + protected override void OnNewClientAccepted(ISocketListener listener, ISocket client, object state) { var paramArray = state as object[]; @@ -79,12 +80,12 @@ protected override void OnNewClientAccepted(ISocketListener listener, Socket cli } } - IAppSession CreateNewSession(Socket listenSocket, IPEndPoint remoteEndPoint, string sessionID) + IAppSession CreateNewSession(ISocket listenSocket, IPEndPoint remoteEndPoint, string sessionID) { if (!DetectConnectionNumber(remoteEndPoint)) return null; - var socketSession = new UdpSocketSession(listenSocket, remoteEndPoint, sessionID); + var socketSession = new UdpSocketSession(listenSocket, remoteEndPoint, sessionID, this.AppServer.SocketFactory); var appSession = AppServer.CreateAppSession(socketSession); if (appSession == null) @@ -105,7 +106,7 @@ IAppSession CreateNewSession(Socket listenSocket, IPEndPoint remoteEndPoint, str } - void ProcessPackageWithSessionID(Socket listenSocket, IPEndPoint remoteEndPoint, byte[] receivedData) + void ProcessPackageWithSessionID(ISocket listenSocket, IPEndPoint remoteEndPoint, byte[] receivedData) { TRequestInfo requestInfo; @@ -169,7 +170,7 @@ void ProcessPackageWithSessionID(Socket listenSocket, IPEndPoint remoteEndPoint, m_RequestHandler.ExecuteCommand(appSession, requestInfo); } - void ProcessPackageWithoutSessionID(Socket listenSocket, IPEndPoint remoteEndPoint, byte[] receivedData) + void ProcessPackageWithoutSessionID(ISocket listenSocket, IPEndPoint remoteEndPoint, byte[] receivedData) { var sessionID = remoteEndPoint.ToString(); var appSession = AppServer.GetSessionByID(sessionID); @@ -211,7 +212,7 @@ bool DetectConnectionNumber(EndPoint remoteEndPoint) protected override ISocketListener CreateListener(ListenerInfo listenerInfo) { - return new UdpSocketListener(listenerInfo); + return new UdpSocketListener(listenerInfo, this.AppServer.SocketFactory); } public override void ResetSessionSecurity(IAppSession session, System.Security.Authentication.SslProtocols security) @@ -227,7 +228,7 @@ Task IActiveConnector.ActiveConnect(EndPoint targetEndPoint Task IActiveConnector.ActiveConnect(EndPoint targetEndPoint, EndPoint localEndPoint) { var taskSource = new TaskCompletionSource(); - var socket = new Socket(targetEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); + var socket = this.AppServer.SocketFactory.Create(targetEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); if (localEndPoint != null) { diff --git a/SocketEngine/UdpSocketSession.cs b/SocketEngine/UdpSocketSession.cs index c8b8b293c..6dbb539c7 100644 --- a/SocketEngine/UdpSocketSession.cs +++ b/SocketEngine/UdpSocketSession.cs @@ -11,24 +11,28 @@ using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; using System.Threading; +using SuperSocket.SocketBase.Sockets; namespace SuperSocket.SocketEngine { class UdpSocketSession : SocketSession { - private Socket m_ServerSocket; + private ISocket m_ServerSocket; + private ISocketFactory m_SocketFactory; - public UdpSocketSession(Socket serverSocket, IPEndPoint remoteEndPoint) + public UdpSocketSession(ISocket serverSocket, IPEndPoint remoteEndPoint, ISocketFactory socketFactory) : base(remoteEndPoint.ToString()) { m_ServerSocket = serverSocket; + m_SocketFactory = socketFactory; RemoteEndPoint = remoteEndPoint; } - public UdpSocketSession(Socket serverSocket, IPEndPoint remoteEndPoint, string sessionID) + public UdpSocketSession(ISocket serverSocket, IPEndPoint remoteEndPoint, string sessionID, ISocketFactory socketFactory) : base(sessionID) { m_ServerSocket = serverSocket; + m_SocketFactory = socketFactory; RemoteEndPoint = remoteEndPoint; } @@ -53,9 +57,9 @@ public override void Start() protected override void SendAsync(SendingQueue queue) { - var e = new SocketAsyncEventArgs(); + var e = m_SocketFactory.CreateSocketAsyncEventArgs(); - e.Completed += new EventHandler(OnSendingCompleted); + e.Completed += new EventHandler(OnSendingCompleted); e.RemoteEndPoint = RemoteEndPoint; e.UserToken = queue; @@ -66,14 +70,14 @@ protected override void SendAsync(SendingQueue queue) OnSendingCompleted(this, e); } - void CleanSocketAsyncEventArgs(SocketAsyncEventArgs e) + void CleanSocketAsyncEventArgs(ISocketAsyncEventArgs e) { e.UserToken = null; - e.Completed -= new EventHandler(OnSendingCompleted); + e.Completed -= new EventHandler(OnSendingCompleted); e.Dispose(); } - void OnSendingCompleted(object sender, SocketAsyncEventArgs e) + void OnSendingCompleted(object sender, ISocketAsyncEventArgs e) { var queue = e.UserToken as SendingQueue; @@ -119,7 +123,7 @@ public override void ApplySecureProtocol() throw new NotSupportedException(); } - protected override bool TryValidateClosedBySocket(out Socket socket) + protected override bool TryValidateClosedBySocket(out ISocket socket) { socket = null; return false;