언어 자료구조 알고리즘/프로그래밍 실습

[C# 실습] 레코드 코팅 - 기계(서버)와 제어기(클라이언트)

언제나휴일 2020. 10. 7. 15:13
반응형

이전 게시글은 RCMachineControl을 제어하는 UI 프로그램에 관한 것입니다. 

 

이번에는 이전 게시글의 UI 프로그램을 다른 프로그램에서 제어할 수 있게 변형할 거예요.

여기에서는 이전에 작성한 UI 프로그램에 서버 기능을 추가하여 레코드 코팅 기계라 말할게요.

그리고 클라이언트 기능과 함께 제어기도 함께 작성합니다.

 

통신으로 주고 받을 메시지 종류

Basic설정(1, 레코드 면적, 코팅 액 투입 구 반경, 스핀 스피드)

소스 레코드 추가(2, 개수,0,0)

코팅액 추가(3, 병수,0,0)

기계 가동(4,0,0,0)

기계 멈춤(5,0,0,0)

 

기계(서버 코드 수정)

패킷을 수신하였을 때 이를 폼에게 전달하기 위한 이벤트 인자 클래스와 대리자를 정의합니다.

RecvPacketEventArgs.cs

using System;

namespace RCManchine_공장_예광탄
{
    public delegate void RecvPacketEventHandler(object sender, RecvPacketEventArgs e);
    public class RecvPacketEventArgs:EventArgs
    {
        /// <summary>
        /// 메시지 ID - 1:Basic 설정, 2:소스 레코드 추가 3: 코팅액 추가 4: 기계 가동 5: 기계 멈춤
        /// </summary>
        public int MsgID { get; private set; }
        public int V1 { get; private set; }
        public int V2 { get; private set; }
        public int V3 { get; private set; }
        public RecvPacketEventArgs(int msgid,int v1,int v2,int v3)
        {
            MsgID = msgid; V1 = v1; V2 = v2; V3 = v3;
        }
    }
}

 


서버 기능을 구현할 클래스를 추가 및 구현합니다.

Manager.cs

using System;
using System.Net;
using System.Net.Sockets;

namespace RCManchine_공장_예광탄
{
    static internal class Manager
    {
        internal static event RecvPacketEventHandler OnRecv;
        internal static void Set(string ip, int port)
        {
            //소켓 생성
            Socket sock = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream,
                ProtocolType.Tcp);
            //네트워크 인터페이스와 결합
            IPAddress addr = IPAddress.Parse(ip);
            IPEndPoint iep = new IPEndPoint(addr, port);
            sock.Bind(iep);
            //백로그 큐 크기 설정
            sock.Listen(5);
            //AcceptLoop            
            AcceptLoopAsync(sock);
        }
        delegate void SockDele(Socket sock);
        static void AcceptLoopAsync(Socket sock)
        {
            SockDele dele = AcceptLoop;
            dele.BeginInvoke(sock, null, null);
        }
        static void AcceptLoop(Socket sock)
        {
            while(true)
            {
                Socket dosock = sock.Accept();
                DoIt(dosock);
            }
        }

        private static void DoIt(Socket dosock)
        {
            byte[] packet = new byte[16];
            dosock.Receive(packet);
            int msgid =  BitConverter.ToInt32(packet, 0);
            int v1 = BitConverter.ToInt32(packet, 4);
            int v2 = BitConverter.ToInt32(packet, 8);
            int v3 = BitConverter.ToInt32(packet, 12);
            dosock.Close();
            if(OnRecv!=null)
            {
                OnRecv(null, new RecvPacketEventArgs(msgid, v1, v2, v3));
            }
        }
    }
}

Form1에 서버 IP와 포트를 지정할 수 있게 컨트롤을 추가 배치합니다.

Form1에 IP, Port 설정을 위한 컨트롤 추가 배치

Form1의 Load 이벤트 핸들러에 서버에서 메시지를 수신하였을 때의 이벤트 핸들러를 등록 및 구현합니다.

그리고 서버 설정 버튼 클릭 이벤트 핸들러도 등록 및 구현합니다.

Form1.cs

using Microsoft.Win32;
using RCMachineControlLib;
using System;
using System.Windows.Forms;
using 콘솔_예광탄;

namespace RCManchine_공장_예광탄
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            rccon.OnEnd += Rccon_OnEnd;
            Manager.OnRecv += Manager_OnRecv;
        }

        private void Manager_OnRecv(object sender, RecvPacketEventArgs e)
        {
            switch(e.MsgID)
            {
                case 1: BasicProc( e.V1, e.V2, e.V3); break;
                case 2: AddSourceProc(e.V1); break;
                case 3: AddLiqProc(e.V1); break;
                case 4: StartProc(); break;
                case 5: StopProc(); break;
               //case 6: 구현 안 할게요. 음냐뤼~ break;
            }
        }

        private void StopProc()
        {
            if(btn_stop.Enabled)
            {
                btn_stop_Click(this, null);
            }
        }

        private void StartProc()
        {
            if(btn_start.Enabled)
            {
                btn_start_Click(this, null);
            }
        }

        private void AddLiqProc(int liq)
        {
            if(btn_liq.Enabled)
            {
                nud_liq.Value = liq;
                btn_liq_Click(this, null);
            }    
        }

        private void AddSourceProc(int source)
        {
            if(btn_source.Enabled)
            {
                nud_source.Value = source;
                btn_source_Click(this, null);
            }
        }

        private void BasicProc( int area, int radius, int speed)
        {
            if (btn_basic.Enabled)
            {
                nud_area.Value = area;
                nud_radius.Value = radius;
                nud_speed.Value = speed;
                btn_basic_Click(this, null);
            }
        }

        private void Rccon_OnEnd(object sender, RCMachineControlLib.EndCotingEventArgs e)
        {
            //인자가 있는 메서드의 크로스 스레드 해결방법
            if (this.InvokeRequired)
            {
                object[] objs = new object[] { sender, e };//전달할 인자를 object 배열 개체로 만듦
                EndCotingEventHandler dele = Rccon_OnEnd;
                this.Invoke(dele, objs);//인자 배열을 두 번째 인자로 전달
            }
            else
            {
                btn_stop.Enabled = false;
                btn_start.Enabled = btn_basic.Enabled = true;
            }
        }

        RCMachine rc;
        private void btn_basic_Click(object sender, EventArgs e)
        {
            if (rc == null)
            {
                rc = new RCMachine();
                nud_source.Enabled = nud_liq.Enabled = true;
                btn_source.Enabled = btn_liq.Enabled = true;
                btn_start.Enabled = true;
                rccon.RCMachine = rc;
            }
            rccon.SetArea(nud_area.Value);
            rccon.SetRadius(nud_radius.Value);
            rccon.SetSpeed(nud_speed.Value);
        }

        private void btn_source_Click(object sender, EventArgs e)
        {
            rccon.AddSource(nud_source.Value);
        }

        private void btn_liq_Click(object sender, EventArgs e)
        {
            rccon.AddLiq(nud_liq.Value);
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            btn_start.Enabled = false;
            btn_stop.Enabled = true;
            btn_basic.Enabled = false;
            rc.Start();
            if(btn_start.Enabled == true)
            {
                MessageBox.Show("가동 조건에 맞지 않습니다.");
            }
        }

        private void btn_stop_Click(object sender, EventArgs e)
        {
            rc.Stop();
            btn_stop.Enabled = false;
            btn_start.Enabled = btn_basic.Enabled = true;
        }

        private void btn_set_Click(object sender, EventArgs e)
        {
            int port = 0;
            int.TryParse(tbox_port.Text, out port);
            Manager.Set(tbox_ip.Text, port);            
        }
    }
}

Form1.Designer.cs

namespace RCManchine_공장_예광탄
{
    partial class Form1
    {
        /// <summary>
        /// 필수 디자이너 변수입니다.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 사용 중인 모든 리소스를 정리합니다.
        /// </summary>
        /// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form 디자이너에서 생성한 코드

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다. 
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
        /// </summary>
        private void InitializeComponent()
        {
            this.rccon = new RCManchine_공장_예광탄.RCMachineControl();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.btn_start = new System.Windows.Forms.Button();
            this.btn_stop = new System.Windows.Forms.Button();
            this.nud_area = new System.Windows.Forms.NumericUpDown();
            this.nud_radius = new System.Windows.Forms.NumericUpDown();
            this.nud_speed = new System.Windows.Forms.NumericUpDown();
            this.nud_source = new System.Windows.Forms.NumericUpDown();
            this.nud_liq = new System.Windows.Forms.NumericUpDown();
            this.btn_basic = new System.Windows.Forms.Button();
            this.btn_source = new System.Windows.Forms.Button();
            this.btn_liq = new System.Windows.Forms.Button();
            this.label6 = new System.Windows.Forms.Label();
            this.btn_set = new System.Windows.Forms.Button();
            this.tbox_port = new System.Windows.Forms.TextBox();
            this.tbox_ip = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.nud_area)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_speed)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_source)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_liq)).BeginInit();
            this.SuspendLayout();
            // 
            // rccon
            // 
            this.rccon.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.rccon.Location = new System.Drawing.Point(403, 0);
            this.rccon.Margin = new System.Windows.Forms.Padding(5);
            this.rccon.Name = "rccon";
            this.rccon.RCMachine = null;
            this.rccon.Size = new System.Drawing.Size(597, 456);
            this.rccon.TabIndex = 0;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 130);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(129, 21);
            this.label1.TabIndex = 1;
            this.label1.Text = "레코드 면적:";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(16, 175);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(129, 21);
            this.label2.TabIndex = 2;
            this.label2.Text = "투입구 반경:";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(20, 226);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(108, 21);
            this.label3.TabIndex = 3;
            this.label3.Text = "회전 속도:";
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(16, 316);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(129, 21);
            this.label4.TabIndex = 4;
            this.label4.Text = "레코드 투입:";
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(16, 368);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(136, 21);
            this.label5.TabIndex = 5;
            this.label5.Text = "코팅 액 투입:";
            // 
            // btn_start
            // 
            this.btn_start.Enabled = false;
            this.btn_start.Location = new System.Drawing.Point(24, 416);
            this.btn_start.Name = "btn_start";
            this.btn_start.Size = new System.Drawing.Size(85, 36);
            this.btn_start.TabIndex = 6;
            this.btn_start.Text = "가동";
            this.btn_start.UseVisualStyleBackColor = true;
            this.btn_start.Click += new System.EventHandler(this.btn_start_Click);
            // 
            // btn_stop
            // 
            this.btn_stop.Enabled = false;
            this.btn_stop.Location = new System.Drawing.Point(115, 416);
            this.btn_stop.Name = "btn_stop";
            this.btn_stop.Size = new System.Drawing.Size(83, 36);
            this.btn_stop.TabIndex = 7;
            this.btn_stop.Text = "멈춤";
            this.btn_stop.UseVisualStyleBackColor = true;
            this.btn_stop.Click += new System.EventHandler(this.btn_stop_Click);
            // 
            // nud_area
            // 
            this.nud_area.Location = new System.Drawing.Point(148, 129);
            this.nud_area.Name = "nud_area";
            this.nud_area.Size = new System.Drawing.Size(120, 32);
            this.nud_area.TabIndex = 8;
            // 
            // nud_radius
            // 
            this.nud_radius.Location = new System.Drawing.Point(148, 173);
            this.nud_radius.Name = "nud_radius";
            this.nud_radius.Size = new System.Drawing.Size(120, 32);
            this.nud_radius.TabIndex = 9;
            // 
            // nud_speed
            // 
            this.nud_speed.Location = new System.Drawing.Point(148, 224);
            this.nud_speed.Name = "nud_speed";
            this.nud_speed.Size = new System.Drawing.Size(120, 32);
            this.nud_speed.TabIndex = 10;
            // 
            // nud_source
            // 
            this.nud_source.Enabled = false;
            this.nud_source.Location = new System.Drawing.Point(148, 314);
            this.nud_source.Name = "nud_source";
            this.nud_source.Size = new System.Drawing.Size(120, 32);
            this.nud_source.TabIndex = 11;
            // 
            // nud_liq
            // 
            this.nud_liq.Enabled = false;
            this.nud_liq.Location = new System.Drawing.Point(148, 366);
            this.nud_liq.Name = "nud_liq";
            this.nud_liq.Size = new System.Drawing.Size(120, 32);
            this.nud_liq.TabIndex = 12;
            // 
            // btn_basic
            // 
            this.btn_basic.Location = new System.Drawing.Point(284, 130);
            this.btn_basic.Name = "btn_basic";
            this.btn_basic.Size = new System.Drawing.Size(88, 126);
            this.btn_basic.TabIndex = 13;
            this.btn_basic.Text = "설정";
            this.btn_basic.UseVisualStyleBackColor = true;
            this.btn_basic.Click += new System.EventHandler(this.btn_basic_Click);
            // 
            // btn_source
            // 
            this.btn_source.Enabled = false;
            this.btn_source.Location = new System.Drawing.Point(284, 314);
            this.btn_source.Name = "btn_source";
            this.btn_source.Size = new System.Drawing.Size(88, 32);
            this.btn_source.TabIndex = 14;
            this.btn_source.Text = "추가";
            this.btn_source.UseVisualStyleBackColor = true;
            this.btn_source.Click += new System.EventHandler(this.btn_source_Click);
            // 
            // btn_liq
            // 
            this.btn_liq.Enabled = false;
            this.btn_liq.Location = new System.Drawing.Point(284, 365);
            this.btn_liq.Name = "btn_liq";
            this.btn_liq.Size = new System.Drawing.Size(88, 33);
            this.btn_liq.TabIndex = 15;
            this.btn_liq.Text = "투입";
            this.btn_liq.UseVisualStyleBackColor = true;
            this.btn_liq.Click += new System.EventHandler(this.btn_liq_Click);
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label6.Location = new System.Drawing.Point(20, 24);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(171, 21);
            this.label6.TabIndex = 38;
            this.label6.Text = "네트워크 서비스 ";
            // 
            // btn_set
            // 
            this.btn_set.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_set.Location = new System.Drawing.Point(284, 48);
            this.btn_set.Name = "btn_set";
            this.btn_set.Size = new System.Drawing.Size(88, 32);
            this.btn_set.TabIndex = 37;
            this.btn_set.Text = "설정";
            this.btn_set.UseVisualStyleBackColor = true;
            this.btn_set.Click += new System.EventHandler(this.btn_set_Click);
            // 
            // tbox_port
            // 
            this.tbox_port.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.tbox_port.Location = new System.Drawing.Point(196, 48);
            this.tbox_port.Name = "tbox_port";
            this.tbox_port.Size = new System.Drawing.Size(72, 32);
            this.tbox_port.TabIndex = 36;
            // 
            // tbox_ip
            // 
            this.tbox_ip.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.tbox_ip.Location = new System.Drawing.Point(16, 48);
            this.tbox_ip.Name = "tbox_ip";
            this.tbox_ip.Size = new System.Drawing.Size(174, 32);
            this.tbox_ip.TabIndex = 35;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 21F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1029, 467);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.btn_set);
            this.Controls.Add(this.tbox_port);
            this.Controls.Add(this.tbox_ip);
            this.Controls.Add(this.btn_liq);
            this.Controls.Add(this.btn_source);
            this.Controls.Add(this.btn_basic);
            this.Controls.Add(this.nud_liq);
            this.Controls.Add(this.nud_source);
            this.Controls.Add(this.nud_speed);
            this.Controls.Add(this.nud_radius);
            this.Controls.Add(this.nud_area);
            this.Controls.Add(this.btn_stop);
            this.Controls.Add(this.btn_start);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.rccon);
            this.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.Margin = new System.Windows.Forms.Padding(5);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.nud_area)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_speed)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_source)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_liq)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private RCMachineControl rccon;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Button btn_start;
        private System.Windows.Forms.Button btn_stop;
        private System.Windows.Forms.NumericUpDown nud_area;
        private System.Windows.Forms.NumericUpDown nud_radius;
        private System.Windows.Forms.NumericUpDown nud_speed;
        private System.Windows.Forms.NumericUpDown nud_source;
        private System.Windows.Forms.NumericUpDown nud_liq;
        private System.Windows.Forms.Button btn_basic;
        private System.Windows.Forms.Button btn_source;
        private System.Windows.Forms.Button btn_liq;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Button btn_set;
        private System.Windows.Forms.TextBox tbox_port;
        private System.Windows.Forms.TextBox tbox_ip;
    }
}

 

제어기(클라이언트)

1. Windows Forms 앱(.NET Framework) 형태의 프로젝트로 추가합니다.

2. Form1에 자식 컨트롤을 배치합니다.

클라이언트의 Form1 자식 컨트롤 배치

각 버튼 클릭 이벤트 핸들러를 추가합니다.

Form1.Designer.cs

namespace RC_공장_클라이언트
{
    partial class Form1
    {
        /// <summary>
        /// 필수 디자이너 변수입니다.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 사용 중인 모든 리소스를 정리합니다.
        /// </summary>
        /// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form 디자이너에서 생성한 코드

        /// <summary>
        /// 디자이너 지원에 필요한 메서드입니다. 
        /// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
        /// </summary>
        private void InitializeComponent()
        {
            this.btn_liq = new System.Windows.Forms.Button();
            this.btn_source = new System.Windows.Forms.Button();
            this.btn_basic = new System.Windows.Forms.Button();
            this.nud_liq = new System.Windows.Forms.NumericUpDown();
            this.nud_source = new System.Windows.Forms.NumericUpDown();
            this.nud_speed = new System.Windows.Forms.NumericUpDown();
            this.nud_radius = new System.Windows.Forms.NumericUpDown();
            this.nud_area = new System.Windows.Forms.NumericUpDown();
            this.btn_stop = new System.Windows.Forms.Button();
            this.btn_start = new System.Windows.Forms.Button();
            this.label5 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.tbox_ip = new System.Windows.Forms.TextBox();
            this.tbox_port = new System.Windows.Forms.TextBox();
            this.btn_set = new System.Windows.Forms.Button();
            this.label6 = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.nud_liq)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_source)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_speed)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_area)).BeginInit();
            this.SuspendLayout();
            // 
            // btn_liq
            // 
            this.btn_liq.Enabled = false;
            this.btn_liq.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_liq.Location = new System.Drawing.Point(301, 317);
            this.btn_liq.Name = "btn_liq";
            this.btn_liq.Size = new System.Drawing.Size(88, 33);
            this.btn_liq.TabIndex = 30;
            this.btn_liq.Text = "투입";
            this.btn_liq.UseVisualStyleBackColor = true;
            this.btn_liq.Click += new System.EventHandler(this.btn_liq_Click);
            // 
            // btn_source
            // 
            this.btn_source.Enabled = false;
            this.btn_source.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_source.Location = new System.Drawing.Point(301, 266);
            this.btn_source.Name = "btn_source";
            this.btn_source.Size = new System.Drawing.Size(88, 32);
            this.btn_source.TabIndex = 29;
            this.btn_source.Text = "추가";
            this.btn_source.UseVisualStyleBackColor = true;
            this.btn_source.Click += new System.EventHandler(this.btn_source_Click);
            // 
            // btn_basic
            // 
            this.btn_basic.Enabled = false;
            this.btn_basic.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_basic.Location = new System.Drawing.Point(301, 117);
            this.btn_basic.Name = "btn_basic";
            this.btn_basic.Size = new System.Drawing.Size(88, 126);
            this.btn_basic.TabIndex = 28;
            this.btn_basic.Text = "설정";
            this.btn_basic.UseVisualStyleBackColor = true;
            this.btn_basic.Click += new System.EventHandler(this.btn_basic_Click);
            // 
            // nud_liq
            // 
            this.nud_liq.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.nud_liq.Location = new System.Drawing.Point(165, 318);
            this.nud_liq.Name = "nud_liq";
            this.nud_liq.Size = new System.Drawing.Size(120, 32);
            this.nud_liq.TabIndex = 27;
            // 
            // nud_source
            // 
            this.nud_source.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.nud_source.Location = new System.Drawing.Point(165, 266);
            this.nud_source.Name = "nud_source";
            this.nud_source.Size = new System.Drawing.Size(120, 32);
            this.nud_source.TabIndex = 26;
            // 
            // nud_speed
            // 
            this.nud_speed.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.nud_speed.Location = new System.Drawing.Point(165, 211);
            this.nud_speed.Name = "nud_speed";
            this.nud_speed.Size = new System.Drawing.Size(120, 32);
            this.nud_speed.TabIndex = 25;
            // 
            // nud_radius
            // 
            this.nud_radius.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.nud_radius.Location = new System.Drawing.Point(165, 160);
            this.nud_radius.Name = "nud_radius";
            this.nud_radius.Size = new System.Drawing.Size(120, 32);
            this.nud_radius.TabIndex = 24;
            // 
            // nud_area
            // 
            this.nud_area.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.nud_area.Location = new System.Drawing.Point(165, 116);
            this.nud_area.Name = "nud_area";
            this.nud_area.Size = new System.Drawing.Size(120, 32);
            this.nud_area.TabIndex = 23;
            // 
            // btn_stop
            // 
            this.btn_stop.Enabled = false;
            this.btn_stop.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_stop.Location = new System.Drawing.Point(132, 368);
            this.btn_stop.Name = "btn_stop";
            this.btn_stop.Size = new System.Drawing.Size(83, 36);
            this.btn_stop.TabIndex = 22;
            this.btn_stop.Text = "멈춤";
            this.btn_stop.UseVisualStyleBackColor = true;
            this.btn_stop.Click += new System.EventHandler(this.btn_stop_Click);
            // 
            // btn_start
            // 
            this.btn_start.Enabled = false;
            this.btn_start.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_start.Location = new System.Drawing.Point(41, 368);
            this.btn_start.Name = "btn_start";
            this.btn_start.Size = new System.Drawing.Size(85, 36);
            this.btn_start.TabIndex = 21;
            this.btn_start.Text = "가동";
            this.btn_start.UseVisualStyleBackColor = true;
            this.btn_start.Click += new System.EventHandler(this.btn_start_Click);
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label5.Location = new System.Drawing.Point(33, 320);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(136, 21);
            this.label5.TabIndex = 20;
            this.label5.Text = "코팅 액 투입:";
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label4.Location = new System.Drawing.Point(33, 268);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(129, 21);
            this.label4.TabIndex = 19;
            this.label4.Text = "레코드 투입:";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label3.Location = new System.Drawing.Point(37, 213);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(108, 21);
            this.label3.TabIndex = 18;
            this.label3.Text = "회전 속도:";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label2.Location = new System.Drawing.Point(33, 162);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(129, 21);
            this.label2.TabIndex = 17;
            this.label2.Text = "투입구 반경:";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label1.Location = new System.Drawing.Point(29, 117);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(129, 21);
            this.label1.TabIndex = 16;
            this.label1.Text = "레코드 면적:";
            // 
            // tbox_ip
            // 
            this.tbox_ip.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.tbox_ip.Location = new System.Drawing.Point(33, 49);
            this.tbox_ip.Name = "tbox_ip";
            this.tbox_ip.Size = new System.Drawing.Size(174, 32);
            this.tbox_ip.TabIndex = 31;
            // 
            // tbox_port
            // 
            this.tbox_port.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.tbox_port.Location = new System.Drawing.Point(213, 49);
            this.tbox_port.Name = "tbox_port";
            this.tbox_port.Size = new System.Drawing.Size(72, 32);
            this.tbox_port.TabIndex = 32;
            // 
            // btn_set
            // 
            this.btn_set.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.btn_set.Location = new System.Drawing.Point(301, 49);
            this.btn_set.Name = "btn_set";
            this.btn_set.Size = new System.Drawing.Size(88, 32);
            this.btn_set.TabIndex = 33;
            this.btn_set.Text = "설정";
            this.btn_set.UseVisualStyleBackColor = true;
            this.btn_set.Click += new System.EventHandler(this.btn_set_Click);
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
            this.label6.Location = new System.Drawing.Point(37, 25);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(52, 21);
            this.label6.TabIndex = 34;
            this.label6.Text = "서버";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(419, 415);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.btn_set);
            this.Controls.Add(this.tbox_port);
            this.Controls.Add(this.tbox_ip);
            this.Controls.Add(this.btn_liq);
            this.Controls.Add(this.btn_source);
            this.Controls.Add(this.btn_basic);
            this.Controls.Add(this.nud_liq);
            this.Controls.Add(this.nud_source);
            this.Controls.Add(this.nud_speed);
            this.Controls.Add(this.nud_radius);
            this.Controls.Add(this.nud_area);
            this.Controls.Add(this.btn_stop);
            this.Controls.Add(this.btn_start);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.nud_liq)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_source)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_speed)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_radius)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.nud_area)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btn_liq;
        private System.Windows.Forms.Button btn_source;
        private System.Windows.Forms.Button btn_basic;
        private System.Windows.Forms.NumericUpDown nud_liq;
        private System.Windows.Forms.NumericUpDown nud_source;
        private System.Windows.Forms.NumericUpDown nud_speed;
        private System.Windows.Forms.NumericUpDown nud_radius;
        private System.Windows.Forms.NumericUpDown nud_area;
        private System.Windows.Forms.Button btn_stop;
        private System.Windows.Forms.Button btn_start;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox tbox_ip;
        private System.Windows.Forms.TextBox tbox_port;
        private System.Windows.Forms.Button btn_set;
        private System.Windows.Forms.Label label6;
    }
}

3. 클라이언트 기능을 구현할 클래스를 추가하고 구현합니다.

Manager.cs

using System.IO;
using System.Net;
using System.Net.Sockets;

namespace RC_공장_클라이언트
{
    static internal class Manager
    {
        static string IP {get; set;}
        static int Port { get; set; }
        internal static void Set(string ip, int port)
        {
            IP = ip;
            Port = port;
        }

        internal static void SetBasic(int area, int radius, int speed)
        {
            Socket sock = Connect();
            byte[] packet = MakePacket(1, area, radius, speed);
            sock.Send(packet);
            sock.Close();
        }

        private static byte[] MakePacket(int msgid, int v1, int v2, int v3)
        {
            byte[] packet = new byte[16];
            MemoryStream ms = new MemoryStream(packet);
            BinaryWriter bw = new BinaryWriter(ms);
            bw.Write(msgid);
            bw.Write(v1);
            bw.Write(v2);
            bw.Write(v3);
            bw.Close();
            ms.Close();
            return packet;
            
        }

        private static Socket Connect()
        {
            //소켓 생성
            Socket sock = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream,
                ProtocolType.Tcp);
            //서버와 연결
            IPAddress servaddr = IPAddress.Parse(IP);
            IPEndPoint iep = new IPEndPoint(servaddr, Port);
            sock.Connect(iep);
            return sock;
        }

        internal static void AddSource(int source)
        {
            Socket sock = Connect();
            byte[] packet = MakePacket(2, source,0,0);
            sock.Send(packet);
            sock.Close();
        }

        internal static void AddReq(int liq)
        {
            Socket sock = Connect();
            byte[] packet = MakePacket(3, liq, 0, 0);
            sock.Send(packet);
            sock.Close();
        }

        internal static void Start()
        {
            Socket sock = Connect();
            byte[] packet = MakePacket(4, 0, 0, 0);
            sock.Send(packet);
            sock.Close();
        }

        internal static void Stop()
        {
            Socket sock = Connect();
            byte[] packet = MakePacket(5, 0, 0, 0);
            sock.Send(packet);
            sock.Close();
        }
    }
}

4. Form1을 구현합니다.

using System;
using System.Windows.Forms;

namespace RC_공장_클라이언트
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_basic_Click(object sender, EventArgs e)
        {
            int area = (int)nud_area.Value;
            int radius = (int)nud_radius.Value;
            int speed = (int)nud_speed.Value;
            Manager.SetBasic(area, radius, speed);            
        }

        private void btn_source_Click(object sender, EventArgs e)
        {
            int source = (int)nud_source.Value;
            Manager.AddSource(source);
        }

        private void btn_liq_Click(object sender, EventArgs e)
        {
            int liq = (int)nud_liq.Value;
            Manager.AddReq(liq);
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            Manager.Start();
        }

        private void btn_stop_Click(object sender, EventArgs e)
        {
            Manager.Stop();
        }


        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btn_set_Click(object sender, EventArgs e)
        {
            int port = 0;
            int.TryParse(tbox_port.Text, out port);
            Manager.Set(tbox_ip.Text, port);
            btn_basic.Enabled = true;
            btn_source.Enabled = true;
            btn_liq.Enabled = true;
            btn_start.Enabled = true;
            btn_stop.Enabled = true;
        }
    }
}

 

이상으로 반도체 장비 제어 시뮬레이션 실습을 마칠게요.

반응형