Пример #1
0
        private void BeginAccept(SocketAsyncEventArgs args)
        {
            LogProvider.Log("checking arguments", "TCPSocket.BeginAccept", LogLevel.Verbose);
            if (args == null)
            {
                args            = _saeas.TakeNext();
                args.UserToken  = new UserDataToken(args.RemoteEndPoint);
                args.Completed += SocketAccept_Completed;

                _connectedSockets.Add(args);
            }

            try
            {
                // Accept a connection and see if the event completed synchronously or not
                LogProvider.Log("attempting to accept a client asynchronously", "TCPSocket.BeginAccept", LogLevel.Verbose);
                if (!_socket.AcceptAsync(args))
                {
                    // We need to process the accept manually
                    LogProvider.Log("but completed synchronously", "TCPSocket.BeginAccept", LogLevel.Verbose);
                    ClientAccepted(args);
                }
            }
            catch
            {
                // we should only jump here when we disconnect all the clients.
                LogProvider.Log("exception thrown", "TCPSocket.BeginAccept", LogLevel.Verbose);
            }
        }
Пример #2
0
        private void Receive()
        {
            SocketAsyncEventArgs args = _saeas.TakeNext();

            byte[] buff = _buffers.TakeNext();
            args.SetBuffer(buff, 0, buff.Length);
            args.Completed     += PacketReceived;
            args.RemoteEndPoint = new IPEndPoint(BindingAddress, Port);

            try
            {
                if (!_socket.ReceiveMessageFromAsync(args))
                {
                    OnPacketReceived(args);
                }
            }
            catch (Exception ex)
            {
                // we should only jump here when we disconnect all the clients.
                Console.WriteLine(ex.Message);
            }
        }
Пример #3
0
        private void BeginReceive(SocketAsyncEventArgs e)
        {
            // see if we can prevent an operation exception
            LogProvider.Log("starting receive", "TCPSocket.BeginReceive", LogLevel.Verbose);
            if (((UserDataToken)e.UserToken).PendingReceiveOperation)
            {
                return;
            }

            byte[] buffer;

            // pattern to avoid duplicating events
            e.Completed -= SocketAccept_Completed;
            e.Completed -= SocketData_Completed;
            e.Completed += SocketData_Completed;
            LogProvider.Log("event handlers re-assigned", "TCPSocket.BeginReceive", LogLevel.Verbose);

            // set the buffer before we start
            if (e.Buffer != null)
            {
                buffer = e.Buffer;
                Array.Clear(buffer, 0, buffer.Length);
            }
            else
            {
                buffer = _buffers.TakeNext();
            }
            LogProvider.Log("buffer cleared/created", "TCPSocket.BeginReceive", LogLevel.Verbose);

            // reset the buffer
            e.SetBuffer(buffer, 0, buffer.Length);

            ((UserDataToken)e.UserToken).PendingReceiveOperation = true;
            LogProvider.Log("pending operation set", "TCPSocket.BeginReceive", LogLevel.Verbose);

            // Accept some data and see if the event completed synchronously or not
            LogProvider.Log("attempting to receive data asynchronously", "TCPSocket.BeginReceive", LogLevel.Verbose);
            if (!Extensions.Coalesce(e.AcceptSocket, e.ConnectSocket, _socket).ReceiveAsync(e))
            {
                LogProvider.Log("but completed synchronously", "TCPSocket.BeginReceive", LogLevel.Verbose);
                // We need to process the data manually
                DataReceived(e);
            }
        }
Пример #4
0
        private void OnPacketReceived(SocketAsyncEventArgs e)
        {
            // Start a new Receive operation straight away
            Receive();

            if (e.ReceiveMessageFromPacketInfo.Address == null)
            {
                // this needs a permenant fix
                Console.WriteLine("Null address, exiting...");
                return;
            }


            // Now process the packet that we have already
            if (e.BytesTransferred <= MessagePrefixLength)
            {
                // Error condition, empty packet
                LogProvider.Log(String.Format("Empty packet received from {0}. Discarding packet.", e.ReceiveMessageFromPacketInfo.Address), "UDPSocket.OnPacketReceived", LogLevel.Minimal);
                ReleaseArgs(e);
                return;
            }

            // Make sure that we aren't the source of the message.
            if (e.ReceiveMessageFromPacketInfo.Address.Equals(((IPEndPoint)_socket.LocalEndPoint).Address))
            {
                LogProvider.Log("Received packet from this node. Disregarding.", "UDPSocket.OnPacketReceived", LogLevel.Verbose);
                ReleaseArgs(e);
                return;
            }

            // Get the message length from the beginning of the packet.
            byte[] arrPrefix = _tempBuffers.TakeNext();
            Buffer.BlockCopy(e.Buffer, e.Offset, arrPrefix, 0, MessagePrefixLength);
            Int32 messageLength = BitConverter.ToInt32(arrPrefix, 0);

            // clear and return the buffer asap
            Array.Clear(arrPrefix, 0, MessagePrefixLength);
            _tempBuffers.Insert(arrPrefix);

            // the number of bytes remaining to store
            Int32 bytesToProcess = e.BytesTransferred - MessagePrefixLength;

            if (bytesToProcess < messageLength)
            {
                LogProvider.Log(String.Format("Missing data from {0}. Discarding packet.", e.ReceiveMessageFromPacketInfo.Address), "UDPSocket.OnPacketReceived", LogLevel.Minimal);
                ReleaseArgs(e);
                return;
            }

            // Create a data buffer
            byte[] data = _buffers.TakeNext(); // new byte[messageLength];

            // Copy the remaining data to the data buffer on the user token
            Buffer.BlockCopy(e.Buffer, e.Offset + MessagePrefixLength, data, 0, messageLength);

            // Thread safe way of triggering the event
            var evnt = OnDataReceived;

            if (evnt != null)
            {
                evnt(e, new SocketDataEventArgs(data, _type, e.ReceiveMessageFromPacketInfo.Address));
                _buffers.Insert(data);
            }

            // Data is safely stored, so unhook the event and return the SocketAsyncEventArgs back to the pool
            ReleaseArgs(e);
        }