Пример #1
0
        private byte[] core_inform_channel_added(byte[] args)
        {
            UInt32 ch_id = Struct.extractUInt32(new List <byte>(args));

            ((Channel)this.GetChannel(ch_id)).isLinked = true;
            return(Struct.packNullTerminatedString(String.Format("Channel with ID {0} set to 'hasLink'", ch_id)).ToArray());
        }
        public ClientMethod(List <byte> data)
        {
            // generate client object based on data received in a run_method control message

            this.id       = Struct.extractUInt32(data);
            this.name     = Struct.extractNullTerminatedString(data);
            this.args     = data.ToArray();
            this.finished = false;
            this.error    = false;
            this.started  = false;
        }
Пример #3
0
        private byte[] core_kill_proc(byte[] args)
        {
            UInt32 proc_id = Struct.extractUInt32(new List <byte>(args));

            //check if proc ID exists (for now only managed procs)
            if (this.pending_client_processes.Contains((int)proc_id))
            {
                ((ClientProcess)this.pending_client_processes[(int)proc_id]).kill();
                //return Struct.packNullTerminatedString(String.Format("Sent kill signal to process with ID {0}", proc_id)).ToArray();
                return(Struct.packUInt32(proc_id).ToArray()); // return process id on success
            }
            else
            {
                throw new ClientMethodException(String.Format("Process with ID {0} not known. Kill signal hasn't been sent", proc_id));
                //return Struct.packNullTerminatedString(String.Format("Process with ID {0} not known. Kill signal hasn't been sent", proc_id)).ToArray();
            }
        }
        private void dispatchControlMessage(List <byte> msg)
        {
            /*
             * This method is called from the input thread (not the processing thread), so time consuming or
             * blocking tasks mustn't be run here
             */
            CH_MSG_TYPE ch_msg_type = (CH_MSG_TYPE)Struct.extractUInt32(msg);

            switch (ch_msg_type)
            {
            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_STATE:
                Console.WriteLine(String.Format("Received STATE request for StreamChannel {0}", this.ID));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_FLUSH:
                Console.WriteLine(String.Format("Received FLUSH request for StreamChannel {0}", this.ID));
                stream.Flush();

                //return message, stating that everything has been written (should be handed by output thread)
                List <byte> flush_response = Struct.packUInt32((UInt32)StreamChannel.CH_MSG_TYPE.CHANNEL_CONTROL_INFORM_FLUSH_SUCCEEDED);
                this.writeControlMessage(flush_response);

                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_CLOSE:
                Console.WriteLine(String.Format("Received CLOSE request for StreamChannel {0}", this.ID));
                this.shouldBeClosed = true;     //no processing overhead
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_POSITION:
                Console.WriteLine(String.Format("Received POSITION request for StreamChannel {0}", this.ID));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_LENGTH:
                Console.WriteLine(String.Format("Received LENGTH request for StreamChannel {0}", this.ID));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_READ_TIMEOUT:
                Console.WriteLine(String.Format("Received READ_TIMEOUT request for StreamChannel {0}", this.ID));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_WRITE_TIMEOUT:
                Console.WriteLine(String.Format("Received WRITE_TIMEOUT request for StreamChannel {0}", this.ID));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_SEEK:
                int offset = Struct.extractInt32(msg);
                int origin = Struct.extractInt32(msg);
                Console.WriteLine(String.Format("Received SEEK request for StreamChannel {0}, count {1}, timeout {2}", this.ID, offset, origin));
                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_WRITE:
                int    size          = Struct.extractInt32(msg);
                byte[] data_to_write = msg.ToArray();

                //the data shouldn't be written from this thread, so the operation has to be moved to processing thread
                this.stream.Write(data_to_write, 0, data_to_write.Length);

                //return message, stating that everything has been written (should be handed by output thread)
                List <byte> write_response = Struct.packUInt32((UInt32)StreamChannel.CH_MSG_TYPE.CHANNEL_CONTROL_INFORM_WRITE_SUCCEEDED);
                write_response = Struct.packInt32(data_to_write.Length, write_response);
                this.writeControlMessage(write_response);

                break;

            case CH_MSG_TYPE.CHANNEL_CONTROL_REQUEST_READ:
                int count   = Struct.extractInt32(msg);
                int timeout = Struct.extractInt32(msg);

                Console.WriteLine(String.Format("Received READ request for StreamChannel {0}, count {1}, timeout {2}", this.ID, count, timeout));


                //the data shouldn't be readen from this thread, blocking would stop the input thread (has to be done from processing thread
                if (this.readbuf.Length < count)
                {
                    this.readbuf = new byte[count];                                  //resize read buffer if needed
                }
                int         read_size = this.stream.Read(this.readbuf, 0, count);
                List <Byte> read_data = new List <byte>(this.readbuf);
                read_data.RemoveRange(read_size, this.readbuf.Length - read_size);

                //return message, stating legngth of read data and the data itself (should be handed by output thread)
                List <byte> read_response = Struct.packUInt32((UInt32)StreamChannel.CH_MSG_TYPE.CHANNEL_CONTROL_INFORM_READ_SUCCEEDED);
                read_response = Struct.packInt32(read_size, read_response);
                read_response.AddRange(read_data);
                this.writeControlMessage(read_response);

                break;

            default:
                Console.WriteLine(String.Format("Received unknown channel message for StreamChannel {0}", this.ID));
                break;
            }
        }
Пример #5
0
        private void __processTransportLayerInput()
        {
            //For now only input of control channel has to be delivered
            // Input for ProcessChannels (STDIN) is directly written to the STDIN pipe of the process (when TransportLayer enqueues data)


            while (this.running)
            {
                this.tl.waitForData();  // blocks if no input from transport layer

                /*
                 * hand over data to respective channels
                 */
                while (this.tl.hasData()) //as long as linklayer has data
                {
                    List <byte> stream = new List <byte>(this.tl.readInputStream());
                    UInt32      ch_id  = Struct.extractUInt32(stream);

                    byte[] data = stream.ToArray(); //the extract method removed the first elements from the List<byte> and we convert back to an array now

                    Channel target_ch = this.GetChannel(ch_id);
                    if (target_ch == null)
                    {
                        Console.WriteLine(String.Format("Received data for channel with ID {0}, this channel doesn't exist!", ch_id));
                        continue;
                    }

                    target_ch.EnqueueInput(data);
                }

                /*
                 * process control channel data
                 */
                while (control_channel.hasPendingInData())
                {
                    List <byte> data = Struct.packByteArray(control_channel.read());

                    // extract control message type
                    UInt32 CtrlMessageType = Struct.extractUInt32(data);

                    switch (CtrlMessageType)
                    {
                    case CTRL_MSG_FROM_SERVER_RUN_METHOD:
                        ClientMethod new_method = new ClientMethod(data);
                        this.addRequestedClientMethodToQueue(new_method);

                        Console.WriteLine(String.Format("Received control message RUN_METHOD! Method ID: {0}, Method Name: {1}, Method Args: {2}", new_method.id, new_method.name, new_method.args));
                        break;

                    case CTRL_MSG_FROM_SERVER_DESTROY:
                        this.SendControlMessage(Client.CTRL_MSG_FROM_CLIENT_DESTROY_RESPONSE);
                        this.stop();
                        break;

                    case CTRL_MSG_FROM_SERVER_CLOSE_CHANNEL:
                        UInt32  channel_id = Struct.extractUInt32(data);
                        Channel ch         = this.GetChannel(channel_id);
                        if (ch != null)
                        {
                            ch.CloseRequestedForLocal = true;
                        }
                        break;

                    default:
                        String data_utf8 = Encoding.UTF8.GetString(data.ToArray());
                        Console.WriteLine(String.Format("Received unknown MESSAGE TYPE for control channel! MessageType: {0}, Data: {1}", CtrlMessageType, data_utf8));
                        break;
                    }
                }
            }
        }