/// <summary> /// Begin Non-Blocking receiver of incoming messages (called after a connection is made) /// </summary> /// /// <param name="SocketFlag">The bitwise combination of Socket Flags (default is None)</param> /// /// <exception cref="CryptoSocketException">Thrown if the Tcp receive operation has failed</exception> public void ReceiveAsync(SocketFlags SocketFlag = SocketFlags.None) { try { // once the client connects then start receiving the commands StateToken cstate = new StateToken(_cltSocket, _cltSocket.ReceiveBufferSize); _cltSocket.BeginReceive(cstate.Buffer, 0, cstate.Buffer.Length, SocketFlag, new AsyncCallback(ReceiveCallback), cstate); } catch (SocketException se) { throw new CryptoSocketException("TcpSocket:ReceiveAsync", "The Tcp receiver has failed!", se); } catch (Exception) { throw; } }
/// <summary> /// Returned when data has been received from a TCP Receive operation /// </summary> /// /// <param name="Owner">The <see cref="StateToken"/> owner object</param> /// <param name="OptionFlag">The option flag containing additional state information</param> public DataReceivedEventArgs(StateToken Owner, int OptionFlag = 0) { this.Owner = Owner; this.OptionFlag = OptionFlag; }
/// <summary> /// Start Non-Blocking listen on a port for an incoming connection /// </summary> /// /// <param name="Address">The IP address assigned to this server</param> /// <param name="Port">The Port number assigned to this server</param> /// <param name="MaxConnections">The maximum number of simultaneous connections allowed (default is 10)</param> /// <param name="Timeout">The wait timeout period</param> /// /// <exception cref="CryptoSocketException">Thrown if the Tcp listen operation has failed</exception> public void ListenAsync(IPAddress Address, int Port, int MaxConnections = 10, int Timeout = Timeout.Infinite) { try { _isServer = true; IPEndPoint ipEP = new IPEndPoint(Address, Port); _lsnSocket = new Socket(ipEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); if (ipEP.AddressFamily == AddressFamily.InterNetworkV6) { _lsnSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); _lsnSocket.Bind(ipEP); } else { // associate the socket with the local endpoint _lsnSocket.Bind(ipEP); } _isListening = true; _lsnSocket.Listen(MaxConnections); // create the state object. StateToken state = new StateToken(_lsnSocket); // accept the incoming clients _lsnSocket.BeginAccept(new AsyncCallback(ListenCallback), state); // blocks the current thread to receive incoming messages _opDone.WaitOne(Timeout); } catch (SocketException se) { throw new CryptoSocketException("TcpSocket:ListenAsync", "The Tcp listener has failed!", se); } catch (Exception) { throw; } }
/// <summary> /// The Listen callback /// </summary> /// /// <param name="Ar">The IAsyncResult</param> /// /// <exception cref="CryptoSocketException">Thrown if the Tcp listen operation has failed</exception> private void ListenCallback(IAsyncResult Ar) { // retrieve the state object and the client socket from the asynchronous state object StateToken state = (StateToken)Ar.AsyncState; Socket srv = state.Client; try { // get the socket for the accepted client connection and put it into the ReadEventArg object user token _cltSocket = srv.EndAccept(Ar); // store the socket SocketAsyncEventArgs readEventArgs = new SocketAsyncEventArgs(); readEventArgs.UserToken = _cltSocket; if (Connected != null) Connected(this, readEventArgs); _isListening = false; // signal done _opDone.Set(); // once the client connects then start receiving the commands StateToken cstate = new StateToken(_cltSocket); // start receiving _cltSocket.BeginReceive(cstate.Buffer, 0, cstate.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), cstate); } catch (ObjectDisposedException) { // disconnected if (DisConnected != null) DisConnected(this, SocketError.ConnectionAborted); } catch (SocketException se) { throw new CryptoSocketException("TcpSocket:ListenCallback", "The Tcp listener has failed!", se); } catch (Exception) { if (_isListening) throw; } }