/// <summary> /// Close an active connection. /// </summary> /// <param name="connection">The connection to close.</param> public void CloseConnection(TcpConnection connection) { try { connection.Dispose(); } catch { // Igore any exceptions } finally { mClientConnections.Remove(connection); } }
/// <summary> /// /// </summary> /// <param name="connection"></param> public void CloseConnection(TcpConnection connection) { try { connection.Dispose(); Thread dataReceivedThread = connection.Tag as Thread; if (dataReceivedThread != null) { lock (mDataReceiveThreads) { mDataReceiveThreads.Remove(dataReceivedThread); } } } catch { // Igore any exceptions } finally { mClientConnections.Remove(connection); } OnDisconnected(new TcpConnectedEventArgs(connection)); }
/// <summary> /// Primary worker thread. /// </summary> /// <param name="socket"></param> private void RunWorker(object socket) { lock (this) { if (mIsShuttingDown == false) { AsyncCallback dataReceivedCallback = ((mReceiveDataInline) && (mUseSynchronousCommunication == false) ? new AsyncCallback(OnDataReceived) : null); TcpConnection connection = new TcpConnection((Socket)socket, dataReceivedCallback); mMessageLength = int.MinValue; mClientConnections.Add(connection); if (mReceiveDataInline && mUseSynchronousCommunication) { #if WINDOWS Thread dataReceiveThread = new Thread(SynchronousReceiveData); dataReceiveThread.Name = "TcpServer ReceiveData Thread"; connection.Tag = dataReceiveThread; mDataReceiveThreads.Add(dataReceiveThread); dataReceiveThread.Start(connection); #else ThreadStartDelegateWrapper threadStartWrapper = new ThreadStartDelegateWrapper(new ThreadStartWrapperHandler(SynchronousReceiveData), connection); Thread dataReceiveThread = new Thread(threadStartWrapper.Start); dataReceiveThread.Name = "TcpServer ReceiveData Thread"; connection.Tag = dataReceiveThread; mDataReceiveThreads.Add(dataReceiveThread); dataReceiveThread.Start(); #endif } OnConnected(new TcpConnectedEventArgs(connection)); } } }
/// <summary> /// /// </summary> /// <param name="connection"></param> private void MarkConnectionForClose(TcpConnection connection) { mConnectionsToClose.Add(connection); }
/// <summary> /// Initializes a new instance of the <see cref="TcpConnectionEventArgs"/> class. /// </summary> /// <param name="connection">The associated connection.</param> /// <param name="data">The associated data.</param> public TcpDataReceivedEventArgs(TcpConnection connection, byte[] data) { mConnection = connection; mData = data; }
/// <summary> /// Start the Tcp server. /// </summary> /// <remarks>This is a non-blocking (asynchronous) call.</remarks> /// <returns>A <seealso cref="Task"/>Task associated with the method.</returns> public async Task Start() { mTcpListener = null; try { mIsShuttingDown = false; mAcceptingConnections = true; mTcpListener = new TcpListener(IPAddress, Port); mTcpListener.Start(MaxPendingConnections); while (true) { Socket socket = await mTcpListener.AcceptSocketAsync(); if (socket == null) { break; } await Task.Run(() => { TcpConnection connection = new TcpConnection(socket, LittleEndianByteOrder); connection.Disconnected += new EventHandler <TcpConnectionEventArgs>(OnDisconnected); connection.DataReceived += new EventHandler <TcpDataReceivedEventArgs>(OnDataReceived); lock (mClientConnections) { mClientConnections.Add(connection); } if (ReceiveDataInline) { connection.ReceiveDataAsync(); } OnConnected(new TcpConnectionEventArgs(connection)); }); } } catch (ObjectDisposedException) { // Supress exception } finally { lock (mClientConnections) { lock (mConnectionsToClose) { foreach (TcpConnection connection in mClientConnections) { mConnectionsToClose.Add(connection); } } CloseMarkedConnections(); } mIsShuttingDown = true; } }
// **NAGIC** /// <summary> /// Asynchronous callback paired with TcpListener.BeginAcceptSocket() /// </summary> /// <param name="asyncResult"></param> // private void OnAcceptSocket(IAsyncResult asyncResult) // { // try // { // TcpListener listener = (TcpListener)asyncResult.AsyncState; // Socket workerSocket = listener.EndAcceptSocket(asyncResult); //#if WINDOWS // Thread workerThread = new Thread(RunWorker); // workerThread.Start(workerSocket); //#else // ThreadStartDelegateWrapper threadStartWrapper = new ThreadStartDelegateWrapper(new ThreadStartWrapperHandler(RunWorker), workerSocket); // Thread workerThread = new Thread(new ThreadStart(threadStartWrapper.Start)); // workerThread.Start(); //#endif // } // catch (ObjectDisposedException) // { // // Consume exception // } // finally // { // mListenerReady.Set(); // } // } /// <summary> /// /// </summary> /// <param name="asyncResult"></param> private void OnDataReceived(IAsyncResult asyncResult) { TcpConnection connection = (TcpConnection)asyncResult.AsyncState; lock (this) { if (mIsShuttingDown) { return; } try { int bytesReceived = connection.Client.EndReceive(asyncResult); if (bytesReceived == 0) { // bytesReceived == 0 when the socket gets shutdown; therefore, remove the connection. connection.ClearReceivedData(); return; } var bytes = new List <byte>(connection.ReceivedData); // ReceivedData creates unnecessary array copy each call. Call it as few times as possible. connection.ClearReceivedData(); bytes.AddRange(connection.ReceivedDataBuffer.Take(bytesReceived)); while (true) { if (mMessageLength == int.MinValue) { if (bytes.Count < 4) { break; } var messageLengthData = bytes.Take(4).ToArray(); if (BitConverter.IsLittleEndian != mLittleEndianByteOrder) { messageLengthData = Library.SwapEndian(messageLengthData); } mMessageLength = BitConverter.ToInt32(messageLengthData, 0); Assert.IsTrue(mMessageLength > 0); bytes.RemoveRange(0, 4); } else { if (bytes.Count < mMessageLength) { break; } OnDataReceived(new TcpDataReceivedEventArgs(connection, bytes.Take(mMessageLength).ToArray())); bytes.RemoveRange(0, mMessageLength); mMessageLength = int.MinValue; } } connection.AppendReceivedData(bytes); connection.InitDataReceivedCallback(OnDataReceived); } catch { CloseConnection(connection); } } }
/// <summary> /// Initializes a new instance of the <see cref="TcpConnectionEventArgs"/> class. /// </summary> /// <param name="connection">The associated connection.</param> public TcpConnectionEventArgs(TcpConnection connection) { Connection = connection; }
/// <summary> /// Initializes a new instance of the <see cref="TcpConnectionEventArgs"/> class. /// </summary> /// <param name="connection">The associated connection.</param> public TcpConnectionEventArgs(TcpConnection connection) { mConnection = connection; }
/// <summary> /// Close the connection. /// </summary> public void Close() { mTcpConnection.Dispose(); mTcpConnection = null; mClient.Close(); }
/// <summary> /// Initializes a new instance of the <see cref="TcpDataReceivedEventArgs"/> class. /// </summary> /// <param name="connection">The associated connection.</param> /// <param name="data">The associated data.</param> public TcpDataReceivedEventArgs(TcpConnection connection, byte[] data) { Connection = connection; Data = data; }
/// <summary> /// Connect to a server. /// </summary> /// <param name="serverIPAddress">The server-side IP address to connect to.</param> /// <param name="serverPort">The server-side port to connect to.</param> public void Connect(IPAddress serverIPAddress, int serverPort) { mServerIPAddress = serverIPAddress; mServerPort = serverPort; mClient.Connect(mServerIPAddress, mServerPort); mTcpConnection = new TcpConnection(mClient.Client, OscPacket.LittleEndianByteOrder); }
/// <summary> /// /// </summary> /// <param name="serverIPAddress"></param> /// <param name="serverPort"></param> public void Connect(IPAddress serverIPAddress, int serverPort) { mClient.Connect(serverIPAddress, serverPort); mTcpConnection = new TcpConnection(mClient.Client, null); }
/// <summary> /// /// </summary> /// <param name="connection"></param> public TcpConnectedEventArgs(TcpConnection connection) { mConnection = connection; }
/// <summary> /// Asynchronous callback paired with TcpListener.BeginAcceptSocket() /// </summary> /// <param name="asyncResult"></param> private void EndAcceptSocket(IAsyncResult asyncResult) { try { TcpListener listener = (TcpListener)asyncResult.AsyncState; Socket socket = listener.EndAcceptSocket(asyncResult); TcpConnection connection = new TcpConnection(socket, mLittleEndianByteOrder); connection.Disconnected += new EventHandler<TcpConnectionEventArgs>(OnDisconnected); connection.DataReceived += new EventHandler<TcpDataReceivedEventArgs>(OnDataReceived); if (mReceiveDataInline) { connection.ReceiveDataAsynchronously(); } mClientConnections.Add(connection); OnConnected(new TcpConnectionEventArgs(connection)); } catch (ObjectDisposedException) { // Consume exception } finally { mListenerReady.Set(); } }
/// <summary> /// /// </summary> /// <param name="connection"></param> /// <param name="data"></param> public TcpDataSentEventArgs(TcpConnection connection, object data) { mConnection = connection; mData = data; }
/// <summary> /// Mark a connection to be closed. /// </summary> /// <param name="connection">The connection to mark.</param> private void MarkConnectionForClose(TcpConnection connection) { mConnectionsToClose.Add(connection); }
/// <summary> /// /// </summary> /// <param name="connection"></param> /// <param name="data"></param> public TcpDataSentEventArgs(TcpConnection connection, object data) { mConnection = connection; mData = data; }