본문 바로가기

프로그래밍&IT/C#

NamedPipe 사용해서 Process간에 데이터 전송

프로세스 간에 NamedPipeServerStream와 NamedPipeClientStream 를 이용해서 Process (프로그램) 간에 데이터 전송

구조

  1. winform기반
  2. Sender와 Receiver 2개의 프로그램 작성

Receiver 프로그램

  • NamedPipeServerStream 사용한다.
  • Sender (Client) 로부터 특정 메세지를 받으면 뭔가 작업을 하는게 목적 (여기선 단순히 "A"라 한다)
  • 처음 시작할때, 작동을 하며
  • Start & Stop 버튼을 만들어 작동을 제어 한다.
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Receiver
{
    public partial class ReceiverForm :Form
    {
        private TextBox textBox;
        private Button startButton;
        private Button stopButton;
        private bool isRunning;

        public ReceiverForm() {
            InitializeComponent();

            textBox = new TextBox { Multiline = true, Dock = DockStyle.Fill };
            startButton = new Button { Text = "Start", Dock = DockStyle.Top };
            stopButton = new Button { Text = "Stop", Dock = DockStyle.Top };

            startButton.Click += StartButton_Click;
            stopButton.Click += StopButton_Click;

            Controls.Add(textBox);
            Controls.Add(startButton);
            Controls.Add(stopButton);

            isRunning = false;

            this.Shown += (s, e) => StartListening();
        }

        private void StartButton_Click(object sender, EventArgs e) {
            StartListening();
        }

        private void StopButton_Click(object sender, EventArgs e) {
            StopListening();
        }

        private void StartListening() {
            if(!isRunning) {
                isRunning = true;
                Task.Run(() => ListenForClients());
                OutputMessage("Server started listening.");
            }
        }

        private void StopListening() {
            isRunning = false;
            OutputMessage("Server stopped listening.");
        }

        private async void ListenForClients() {
            while(isRunning) {
                using(NamedPipeServerStream pipeServer = new NamedPipeServerStream("MyPipe")) {
                    try {
                        OutputMessage("Waiting for connection.");
                        pipeServer.WaitForConnection();

                        using(StreamReader reader = new StreamReader(pipeServer)) {
                            string message = reader.ReadLine();
                            OutputMessage($"Received: {message}");
                            
                            //"A"를 받으면 뭔가 작업을 하는걸로 생각한다.
                            if(message == "A") {
                                await Task.Delay(3000);
                                OutputMessage("Finished Something");
                            }
                        }
                    }
                    catch(Exception ex) {
                        OutputMessage("Error: {ex.Message}");
                    }
                }
            }
        }

        private void OutputMessage(string msg) {
            Invoke(new Action(() => textBox.AppendText($"{msg}\r\n")));
        }

    }
}

 

Sender

  • NamedPipeClientStream 활용
  • Send버튼구현 및 그 결과를 Textbox에 쓴다
using System.IO.Pipes;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        private TextBox inputBox;
        private Button sendButton;

        public Form1()
        {
            inputBox = new TextBox { Dock = DockStyle.Top, Name="btnInput" };
            sendButton = new Button { Text = "Send", Dock = DockStyle.Bottom, Name="btnSend" };
            sendButton.Click += SendButton_Click;

            Controls.Add(inputBox);
            Controls.Add(sendButton);

            InitializeComponent();
        }

        private void SendButton_Click(object? sender, EventArgs e) {
            using(NamedPipeClientStream pipeClient = new NamedPipeClientStream("MyPipe")) {
                pipeClient.Connect();

                using(StreamWriter writer = new StreamWriter(pipeClient)) {
                    writer.AutoFlush = true;
                    string message = inputBox.Text;
                    writer.WriteLine(message);
                }
            }
        }

    }
}