わいずふぁくとりいがプログラムの話題をウィキします。

(ファイルトランスポータプロトコル - 5)

 Windows側(WinFileTransport)の主要な実装を掲載します。





Form1.cs

//  FileTransportClient - Form1
//  2020.10.?? - 2021.01.17 ysfactory
//
using System;
using System.Windows.Forms;

namespace WinFileTransport
{
    public partial class Form1 : Form
    {
        private FTClient m_ft_client = new FTClient();
        private FTProcess m_ft_cmd_proc = new FTProcess();
        private FTDispatcher m_ft_dispatcher = new FTDispatcher();
        private FTReceiver m_ft_receiver = new FTReceiver();
        private FTSession m_ft_session = new FTSession();
        private FileTransporter m_file_transporter = new FileTransporter();

        public Form1()
        {
            InitializeComponent();

            m_ft_client.SetReceiver(m_ft_receiver);
            m_ft_client.SetSession(m_ft_session);

            m_ft_cmd_proc.SetTransporter(m_file_transporter);
            m_ft_cmd_proc.SetSender(m_ft_client);
            m_ft_cmd_proc.SetDispatcher(m_ft_dispatcher);

            m_ft_dispatcher.SetReceiver(m_ft_receiver);
            m_ft_session.SetSender(m_ft_client);
            m_ft_session.SetReceiver(m_ft_receiver);

            m_ft_client.evStatusMessage += OnStatusMessage;
            m_file_transporter.evStatusMessage += OnStatusMessage;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                m_ft_client.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        delegate void DelegateStatusMessage(string message);
        private void OnStatusMessage(string message)
        {
            if (this.InvokeRequired)
            {
                Invoke(new DelegateStatusMessage(OnStatusMessage), message);
            }
            else
            {
                textBoxStatus.AppendText(message);
            }
        }

        private void buttonClear_Click(object sender, EventArgs e)
        {
            textBoxStatus.Clear();
        }
    }
}

FileTransporter.cs

//  FileTransportClient - FileTransporter
//  2020.11.14 - 2020.12.04 ysfactory
//
using System;
using System.IO;
using System.Text;

namespace WinFileTransport
{
    class FileTransporter
    {
        const string SHARD_HOLDER = @"..\..\..\..\..\path_a_work";
        string m_holder = SHARD_HOLDER;
        FileStream m_stream;

        public void SetHolder(string holder)
        {
            m_holder = holder;
        }

        public bool Append(string filename)
        {
            try
            {
                m_stream?.Dispose();
                string path = Path.Combine(m_holder, filename);
                m_stream = new FileStream(path, FileMode.Append, FileAccess.Write);
                return true;
            }
            catch (Exception ex)
            {
                StatusMessageLn(ex.Message);
                return false;
            }
        }

        public bool Write(byte[] data)
        {
            try
            {
                m_stream.Write(data, 0, data.Length);
                StatusMessage(Encoding.ASCII.GetString(data));
                return true;
            }
            catch (Exception ex)
            {
                StatusMessageLn(ex.Message);
                return false;
            }
        }

        public bool Close()
        {
            try
            {
                m_stream.Dispose();
                m_stream = null;
                return true;
            }
            catch (Exception ex)
            {
                StatusMessageLn(ex.Message);
                return false;
            }
        }

        public static void Test()
        {
            FileTransporter transporter = new FileTransporter();
            transporter.Append("Test.txt");
            transporter.Write(Encoding.ASCII.GetBytes("Test.txt"));
            transporter.Close();
        }

        public delegate void dgtStatusMessage(string message);
        public event dgtStatusMessage evStatusMessage;

        void StatusMessageLn(string message)
        {
            StatusMessage(message + Environment.NewLine);
        }

        void StatusMessage(string message)
        {
            evStatusMessage?.Invoke(message);
        }
    }
}

FTClient.cs

//  FileTransportClient - FTClient (FTSender)
//  2020.10.?? - 2020.12.04 ysfactory
//
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace WinFileTransport
{
    class FTClient
    {
        const string HOST = "192.168.3.9";
        const int PORT = 50001;
        //const int ALIVE_CYCLE_TIME = 60 * 1000;
        //const int RETRY_PAUSE_TIME = 60 * 1000;
        const int ALIVE_CYCLE_TIME = 10 * 1000;
        const int RETRY_PAUSE_TIME = 10 * 1000;

        TcpClient m_tcpclient;
        NetworkStream m_net_stream;
        FTReceiver m_receiver;
        FTSession m_session;
        readonly object m_frame_lock = new object();

        public void SetReceiver(FTReceiver receiver)
        {
            m_receiver = receiver;
        }

        public void SetSession(FTSession session)
        {
            m_session = session;
        }

        public void Start()
        {
            Task.Run(async () =>
            {
                try
                {
                    await Loop();
                }
                catch (Exception ex)
                {
                    StatusMessageLn(ex.Message);
                }
            });
        }

        async Task Loop()
        {
            for (;;)
            {
                try
                {
                    Connect();
                    StartReceive();
                    StatusMessageLn("Connected.");
                    m_session.PathCommand("path_a");
                    for (;;)
                    {
                        m_session.SendAlive();   //Alive
                        await Task.Delay(ALIVE_CYCLE_TIME);
                    }
                }
                catch (Exception ex)
                {
                    StatusMessageLn(ex.Message);
                }
                await Task.Delay(RETRY_PAUSE_TIME);
            }
        }

        void Connect()
        {
            //TcpClientを作成し、サーバーと接続する
            m_tcpclient = new TcpClient(HOST, PORT);
            //NetworkStreamを取得する
            m_net_stream = m_tcpclient.GetStream();
        }

        //送信
        public void SendFrame(string frame)
        {
            SendFrame(Encoding.ASCII.GetBytes(frame));
        }

        public void SendFrame(byte[] frame)
        {
            lock (m_frame_lock)
            {
                m_net_stream.Write(frame, 0, frame.Length);
            }
        }

        //受信
        byte[] __receive_buffer = new byte[1];
        void StartReceive()
        {
            m_net_stream.BeginRead(__receive_buffer, 0, 1, OnReceivedByte, null);
        }

        void OnReceivedByte(IAsyncResult result)
        {
            try
            {
                m_net_stream.EndRead(result);
                try
                {
                    m_receiver.OnReceivedByte(__receive_buffer[0]);
                }
                catch (Exception ex)
                {
                    StatusMessageLn(ex.Message);
                }
                StartReceive();
            }
            catch (Exception ex)
            {
                StatusMessageLn(ex.Message);
            }
        }

        public delegate void dgtStatusMessage(string message);
        public event dgtStatusMessage evStatusMessage;

        void StatusMessageLn(string message)
        {
            StatusMessage(message + Environment.NewLine);
        }

        void StatusMessage(string message)
        {
            evStatusMessage?.Invoke(message);
        }
    }
}

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

管理人/副管理人のみ編集できます