/// <SUMMARY> /// Callback function: A new connection is waiting. /// </SUMMARY> private void ConnectionReady_Handler(IAsyncResult ar) { lock (_padLock) { if (_listener == null) { return; } Socket conn = _listener.EndAccept(ar); if (_connections.Count >= _maxConnections) { //Max number of connections reached. string msg = "SE001: Server busy"; conn.Send(Encoding.UTF8.GetBytes(msg), 0, msg.Length, SocketFlags.None); conn.Shutdown(SocketShutdown.Both); conn.Close(); } else { //Start servicing a new connection ChoConnectionState st = new ChoConnectionState(); st.Connection = conn; st.Server = this; st.Serializer = Serializer; st.Provider = (ChoTcpServiceProvider)_provider.Clone(); st.Buffer = new byte[4]; _connections.Add(st); //Queue the rest of the job to be executed latter ThreadPool.QueueUserWorkItem(AcceptConnection, st); } //Resume the listening callback loop _listener.BeginAccept(ConnectionReady, null); } }
public override void OnReceiveData(ChoConnectionState state) { while (state.AvailableData > 0) { int readBytes = state.Read(state.Buffer, 0, state.Buffer.Length); byte[] buffer = state.Buffer.Take(readBytes).ToArray(); if (_inbuffer == null) { _inbuffer = buffer; _headerFound = false; } else { _inbuffer = ChoByteArrayEx.Combine(_inbuffer, buffer); } try { if (!_headerFound) { _msgBodySize = ProcessHeader(out _headerFound); } if (_headerFound) { ProcessBody(state, _msgBodySize); } } catch (Exception ex) { ChoTrace.Write(ex); } } }
private bool ProcessBody(ChoConnectionState state, int msgBodySize) { if (_inbuffer.Length < msgBodySize) { return(false); } try { MemoryStream instream = new MemoryStream(); instream.Write(_inbuffer, 0, msgBodySize); _inbuffer = ChoByteArrayEx.SubArray(_inbuffer, msgBodySize); instream.Flush(); instream.Position = 0; InvokeObjectReceived(state, instream.GetBuffer()); } catch (Exception ex) { ChoTrace.Write(ex); } finally { //_inbuffer = null; _headerFound = false; } return(true); }
public override void OnReceiveData(ChoConnectionState state) { while (state.AvailableData > 0) { int readBytes = state.Read(state._buffer, 0, state._buffer.Length); byte[] buffer = state._buffer.Take(readBytes).ToArray(); if (_inbuffer == null) { _inbuffer = buffer; } else { _inbuffer = ChoByteArrayEx.Combine(_inbuffer, buffer); } if (!_headerFound) { _msgBodySize = ProcessHeader(); if (_headerFound) { ProcessBody(); } } else { ProcessBody(); } } }
/// <summary> /// Send an object. /// </summary> /// <param name="value">Object to send</param> /// <remarks> /// Must be marked as serializable and connection must be open. /// </remarks> //public override byte[] ToByteArray(object value) //{ // //var stream = new MemoryStream(); // //stream.Position = 0; // //_formatter.Serialize(stream, value); // byte[] body = _serializer.Serialize(value) as byte[]; // stream.GetBuffer(); // if (body == null) return null; // var header = new byte[8]; // byte[] streamLength = BitConverter.GetBytes((Int32)body.Length); // Buffer.BlockCopy(_version, 0, header, 0, _version.Length); // Buffer.BlockCopy(streamLength, 0, header, _version.Length, streamLength.Length); // return ChoByteArrayEx.Combine(header, body.Take((Int32)body.Length).ToArray()); //} private void InvokeObjectReceived(ChoConnectionState state, byte[] payload) { if (state == null || payload == null) { return; } state.InvokeObjectReceived(payload); }
private void ReceivedDataReady(IAsyncResult ar) { ChoConnectionState st = ar.AsyncState as ChoConnectionState; try { st.Connection.EndReceive(ar); //Im considering the following condition as a signal that the //remote host droped the connection. if (st.Connection.Available == 0) { return; } else { try { _provider.OnReceiveData(st); } catch (ChoFatalApplicationException) { throw; } catch { //report error in the provider } //Resume ReceivedData callback loop if (st.Connection.Connected) { try { st.Connection.BeginReceive(st.Buffer, 0, 0, SocketFlags.None, ReceivedDataReady, st); } catch (Exception innerEx) { ChoTrace.Error(innerEx); HandleDisconnected(); } } } } catch (ObjectDisposedException) { HandleDisconnected(); } catch (ChoFatalApplicationException) { throw; } catch (Exception ex) { ChoTrace.Error(ex); HandleDisconnected(); } }
public override void OnAcceptConnection(ChoConnectionState state) { _receivedStr = ""; if (!state.Write(Encoding.UTF8.GetBytes( "Hello World!\r\n"), 0, 14)) { state.EndConnection(); } //if write fails... then close connection }
/// <SUMMARY> /// Removes a connection from the list /// </SUMMARY> internal void DropConnection(ChoConnectionState st) { lock (_padLock) { if (st.Connection != null && st.Connection.Connected) { st.Connection.Shutdown(SocketShutdown.Both); st.Connection.Close(); } if (_connections.Contains(st)) { _connections.Remove(st); } } }
/// <SUMMARY> /// Executes OnReceiveData method from the service provider. /// </SUMMARY> private void ReceivedDataReady_Handler(IAsyncResult ar) { ChoConnectionState st = ar.AsyncState as ChoConnectionState; try { st.Connection.EndReceive(ar); //Im considering the following condition as a signal that the //remote host droped the connection. if (st.Connection.Available == 0) { DropConnection(st); } else { try { st.Provider.OnReceiveData(st); } catch { //report error in the provider } //Resume ReceivedData callback loop if (st.Connection.Connected) { try { st.Connection.BeginReceive(st.Buffer, 0, 0, SocketFlags.None, ReceivedDataReady, st); } catch (Exception) { DropConnection(st); } } } } catch { try { DropConnection(st); } catch { } } }
private void Connect() { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(_localEP); ChoConnectionState st = _connection = new ChoConnectionState(); st.Connection = _socket; st.Client = this; st.Serializer = Serializer; st.Provider = (ChoTcpServiceProvider)_provider.Clone(); st.Buffer = new byte[1024]; if (_socket.Connected) { RaiseConnected(); _socket.BeginReceive(_connection.Buffer, 0, 0, SocketFlags.None, ReceivedDataReady, _connection); } }
public override void OnReceiveData(ChoConnectionState state) { byte[] buffer = new byte[1024]; while (state.AvailableData > 0) { int readBytes = state.Read(buffer, 0, 1024); if (readBytes > 0) { _receivedStr += Encoding.UTF8.GetString(buffer, 0, readBytes); if (_receivedStr.IndexOf("<EOF>") >= 0) { state.Write(Encoding.UTF8.GetBytes(_receivedStr), 0, _receivedStr.Length); _receivedStr = ""; } } else { state.EndConnection(); } //If read fails then close connection } }
/// <SUMMARY> /// Executes OnAcceptConnection method from the service provider. /// </SUMMARY> private void AcceptConnection_Handler(object state) { ChoConnectionState st = state as ChoConnectionState; try { st.Provider.OnAcceptConnection(st); } catch { //report error in provider... Probably to the EventLog } try { //Starts the ReceiveData callback loop if (st.Connection.Connected) { st.Connection.BeginReceive(st.Buffer, 0, 0, SocketFlags.None, ReceivedDataReady, st); } } catch { DropConnection(st); } }
public override void OnReceiveData(ChoConnectionState state) { }
public override void OnAcceptConnection(ChoConnectionState state) { }
public override void OnDropConnection(ChoConnectionState state) { }
public override void OnDropConnection(ChoConnectionState state) { //Nothing to clean here }
/// <SUMMARY> /// Gets executed when the server needs to shutdown the connection. /// </SUMMARY> public abstract void OnDropConnection(ChoConnectionState state);
/// <SUMMARY> /// Gets executed when the server detects incoming data. /// This method is called only if /// OnAcceptConnection has already finished. /// </SUMMARY> public abstract void OnReceiveData(ChoConnectionState state);
/// <SUMMARY> /// Gets executed when the server accepts a new connection. /// </SUMMARY> public abstract void OnAcceptConnection(ChoConnectionState state);