All pastes #2110929 Raw Edit

Stuff

public text v1 · immutable
#2110929 ·published 2012-02-07 19:56 UTC
rendered paste body
        // EXAMPLE IMPLEMENTATION
        Action<IEnumerable<IMessage>> receiveCallback;

        private void BeginReceive() {
            receiveCallback = new Action<IEnumerable<IMessage>>(MessageLoop);
            ReceiveAsync(receiveCallback);
        }

        private void MessageLoop(IEnumerable<IMessage> messages) {

            foreach (IMessage message in messages) {
                switch (message.Id) {
                    case MsgId.BitField:
                    case MsgId.Choke:
                    case MsgId.Interested:
                        break;
                }
            }

            ReceiveAsync(receiveCallback);
        }

        // SOCKET LOGIC
        public virtual void ReceiveAsync(Action<IEnumerable<IMessage>> complete) {
            int count = BaseSocket.Available > 4 ? BaseSocket.Available : 4;
            if (count > 8192) count = 8192;

            ReceiveState state = new ReceiveState(count, complete);

            recvArgs.UserToken = state;
            recvArgs.SetBuffer(0, count);

            CallReceive(recvArgs);
        }

        public virtual void ReceiveComplete(object sender, SocketAsyncEventArgs e) {

            if (e.BytesTransferred > 0) {
                ReceiveState state = (ReceiveState)e.UserToken;
                state.Received += e.BytesTransferred;

                if (state.Received < state.Length) {
                    recvArgs.UserToken = state;
                    recvArgs.SetBuffer(state.Received, (state.Length - state.Received));

                    CallReceive(recvArgs);
                }
                else {
                    e.UserToken = null;

                    byte[] buffer = new byte[state.Length];
                    Array.Copy(e.Buffer, 0, buffer, 0, buffer.Length);

                    MessageReader reader = new MessageReader(buffer);

                    while (reader.Remaining >= 4) {
                        int length = reader.ReadInt32();

                        if (reader.Remaining < length) {
                            reader.Position -= 4;
                            buffer = reader.ReadBytes(reader.Remaining);

                            Array.Copy(buffer, 0, e.Buffer, 0, buffer.Length);

                            state.Length = length + 4;
                            state.Received = buffer.Length;

                            recvArgs.SetBuffer(state.Received, (state.Length - state.Received));

                            CallReceive(recvArgs);
                            return;
                        }
                        else state.Messages.Add(Formatter.Unformat((byte)reader.ReadByte(), reader.ReadBytes(length - 1)));
                    }

                    state.Complete(state.Messages);
                }
            }
        }

        private void CallReceive(SocketAsyncEventArgs args) {
            try {
                if (!BaseSocket.ReceiveAsync(args))
                    ReceiveComplete(BaseSocket, args);
            }
            catch (ObjectDisposedException) { }
            catch (Exception e) {

            }
        }