diff --git a/FastTunnel.Core/AsyncListener.cs b/FastTunnel.Core/AsyncListener.cs
index a0d00ab..f9c93d0 100644
--- a/FastTunnel.Core/AsyncListener.cs
+++ b/FastTunnel.Core/AsyncListener.cs
@@ -20,6 +20,7 @@ namespace FastTunnel.Core
int m_numConnectedSockets;
+ bool shutdown = false;
IListenerDispatcher _requestDispatcher;
Socket listenSocket;
@@ -38,6 +39,7 @@ namespace FastTunnel.Core
public void Listen(IListenerDispatcher requestDispatcher)
{
+ shutdown = false;
_requestDispatcher = requestDispatcher;
listenSocket.Listen(100);
@@ -45,7 +47,30 @@ namespace FastTunnel.Core
StartAccept(null);
}
- public void StartAccept(SocketAsyncEventArgs acceptEventArg)
+ public void ShutdownAndClose()
+ {
+ if (shutdown)
+ return;
+
+ try
+ {
+ if (listenSocket.Connected)
+ {
+ listenSocket.Shutdown(SocketShutdown.Both);
+ }
+ }
+ catch (Exception)
+ {
+ }
+ finally
+ {
+ shutdown = true;
+ listenSocket.Close();
+ Interlocked.Decrement(ref m_numConnectedSockets);
+ }
+ }
+
+ private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (acceptEventArg == null)
{
@@ -78,6 +103,7 @@ namespace FastTunnel.Core
// Accept the next connection request
StartAccept(e);
+ // 将此客户端交由Dispatcher进行管理
_requestDispatcher.Dispatch(accept);
}
else
@@ -90,21 +116,5 @@ namespace FastTunnel.Core
{
ProcessAccept(e);
}
-
- public void ShutdownAndClose()
- {
- try
- {
- listenSocket.Shutdown(SocketShutdown.Both);
- }
- catch (Exception)
- {
- }
- finally
- {
- listenSocket.Close();
- Interlocked.Decrement(ref m_numConnectedSockets);
- }
- }
}
}
diff --git a/FastTunnel.Core/Server.cs b/FastTunnel.Core/Server.cs
deleted file mode 100644
index ffd4e33..0000000
--- a/FastTunnel.Core/Server.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-
-namespace FastTunnel.Core
-{
- // Implements the connection logic for the socket server.
- // After accepting a connection, all data read from the client
- // is sent back to the client. The read and echo back to the client pattern
- // is continued until the client disconnects.
- class Server
- {
- private int m_numConnections; // the maximum number of connections the sample is designed to handle simultaneously
- private int m_receiveBufferSize;// buffer size to use for each socket I/O operation
- BufferManager m_bufferManager; // represents a large reusable set of buffers for all socket operations
- const int opsToPreAlloc = 2; // read, write (don't alloc buffer space for accepts)
- Socket listenSocket; // the socket used to listen for incoming connection requests
- // pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations
- SocketAsyncEventArgsPool m_readWritePool;
- int m_totalBytesRead; // counter of the total # bytes received by the server
- int m_numConnectedSockets; // the total number of clients connected to the server
- Semaphore m_maxNumberAcceptedClients;
-
- // Create an uninitialized server instance.
- // To start the server listening for connection requests
- // call the Init method followed by Start method
- //
- // the maximum number of connections the sample is designed to handle simultaneously
- // buffer size to use for each socket I/O operation
- public Server(int numConnections, int receiveBufferSize)
- {
- m_totalBytesRead = 0;
- m_numConnectedSockets = 0;
- m_numConnections = numConnections;
- m_receiveBufferSize = receiveBufferSize;
- // allocate buffers such that the maximum number of sockets can have one outstanding read and
- //write posted to the socket simultaneously
- m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc,
- receiveBufferSize);
-
- m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
- m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
- }
-
- // Initializes the server by preallocating reusable buffers and
- // context objects. These objects do not need to be preallocated
- // or reused, but it is done this way to illustrate how the API can
- // easily be used to create reusable objects to increase server performance.
- //
- public void Init()
- {
- // Allocates one large byte buffer which all I/O operations use a piece of. This gaurds
- // against memory fragmentation
- m_bufferManager.InitBuffer();
-
- // preallocate pool of SocketAsyncEventArgs objects
- SocketAsyncEventArgs readWriteEventArg;
-
- for (int i = 0; i < m_numConnections; i++)
- {
- //Pre-allocate a set of reusable SocketAsyncEventArgs
- readWriteEventArg = new SocketAsyncEventArgs();
- readWriteEventArg.Completed += new EventHandler(IO_Completed);
- readWriteEventArg.UserToken = new AsyncUserToken();
-
- // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
- m_bufferManager.SetBuffer(readWriteEventArg);
-
- // add SocketAsyncEventArg to the pool
- m_readWritePool.Push(readWriteEventArg);
- }
- }
-
- // Starts the server such that it is listening for
- // incoming connection requests.
- //
- // The endpoint which the server will listening
- // for connection requests on
- public void Start(IPEndPoint localEndPoint)
- {
- // create the socket which listens for incoming connections
- listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
- listenSocket.Bind(localEndPoint);
- // start the server with a listen backlog of 100 connections
- listenSocket.Listen(100);
-
- // post accepts on the listening socket
- StartAccept(null);
-
- //Console.WriteLine("{0} connected sockets with one outstanding receive posted to each....press any key", m_outstandingReadCount);
- Console.WriteLine("Press any key to terminate the server process....");
- Console.ReadKey();
- }
-
- // Begins an operation to accept a connection request from the client
- //
- // The context object to use when issuing
- // the accept operation on the server's listening socket
- public void StartAccept(SocketAsyncEventArgs acceptEventArg)
- {
- if (acceptEventArg == null)
- {
- acceptEventArg = new SocketAsyncEventArgs();
- acceptEventArg.Completed += new EventHandler(AcceptEventArg_Completed);
- }
- else
- {
- // socket must be cleared since the context object is being reused
- acceptEventArg.AcceptSocket = null;
- }
-
- m_maxNumberAcceptedClients.WaitOne();
- bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
- if (!willRaiseEvent)
- {
- ProcessAccept(acceptEventArg);
- }
- }
-
- // This method is the callback method associated with Socket.AcceptAsync
- // operations and is invoked when an accept operation is complete
- //
- void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
- {
- ProcessAccept(e);
- }
-
- private void ProcessAccept(SocketAsyncEventArgs e)
- {
- Interlocked.Increment(ref m_numConnectedSockets);
- Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",
- m_numConnectedSockets);
-
- // Get the socket for the accepted client connection and put it into the
- //ReadEventArg object user token
- SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
- ((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;
-
- // As soon as the client is connected, post a receive to the connection
- bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
- if (!willRaiseEvent)
- {
- ProcessReceive(readEventArgs);
- }
-
- // Accept the next connection request
- StartAccept(e);
- }
-
- // This method is called whenever a receive or send operation is completed on a socket
- //
- // SocketAsyncEventArg associated with the completed receive operation
- void IO_Completed(object sender, SocketAsyncEventArgs e)
- {
- // determine which type of operation just completed and call the associated handler
- switch (e.LastOperation)
- {
- case SocketAsyncOperation.Receive:
- ProcessReceive(e);
- break;
- case SocketAsyncOperation.Send:
- ProcessSend(e);
- break;
- default:
- throw new ArgumentException("The last operation completed on the socket was not a receive or send");
- }
- }
-
- // This method is invoked when an asynchronous receive operation completes.
- // If the remote host closed the connection, then the socket is closed.
- // If data was received then the data is echoed back to the client.
- //
- private void ProcessReceive(SocketAsyncEventArgs e)
- {
- // check if the remote host closed the connection
- AsyncUserToken token = (AsyncUserToken)e.UserToken;
- if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
- {
- //increment the count of the total bytes receive by the server
- Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
- Console.WriteLine("The server has read a total of {0} bytes", m_totalBytesRead);
-
- //echo the data received back to the client
- e.SetBuffer(e.Offset, e.BytesTransferred);
- bool willRaiseEvent = token.Socket.SendAsync(e);
- if (!willRaiseEvent)
- {
- ProcessSend(e);
- }
- }
- else
- {
- CloseClientSocket(e);
- }
- }
-
- // This method is invoked when an asynchronous send operation completes.
- // The method issues another receive on the socket to read any additional
- // data sent from the client
- //
- //
- private void ProcessSend(SocketAsyncEventArgs e)
- {
- if (e.SocketError == SocketError.Success)
- {
- // done echoing data back to the client
- AsyncUserToken token = (AsyncUserToken)e.UserToken;
- // read the next block of data send from the client
- bool willRaiseEvent = token.Socket.ReceiveAsync(e);
- if (!willRaiseEvent)
- {
- ProcessReceive(e);
- }
- }
- else
- {
- CloseClientSocket(e);
- }
- }
-
- private void CloseClientSocket(SocketAsyncEventArgs e)
- {
- AsyncUserToken token = e.UserToken as AsyncUserToken;
-
- // close the socket associated with the client
- try
- {
- token.Socket.Shutdown(SocketShutdown.Send);
- }
- // throws if client process has already closed
- catch (Exception) { }
- token.Socket.Close();
-
- // decrement the counter keeping track of the total number of clients connected to the server
- Interlocked.Decrement(ref m_numConnectedSockets);
-
- // Free the SocketAsyncEventArg so they can be reused by another client
- m_readWritePool.Push(e);
-
- m_maxNumberAcceptedClients.Release();
- Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets);
- }
- }
-
- internal class AsyncUserToken
- {
- public System.Net.Sockets.Socket Socket { get; set; }
- }
-}
diff --git a/FastTunnel.Core/SuiDao.Core.csproj.user b/FastTunnel.Core/SuiDao.Core.csproj.user
deleted file mode 100644
index 966b4ff..0000000
--- a/FastTunnel.Core/SuiDao.Core.csproj.user
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- true
-
-
\ No newline at end of file