이전 게시글은 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의 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.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;
}
}
}
이상으로 반도체 장비 제어 시뮬레이션 실습을 마칠게요.
'언어 자료구조 알고리즘 > 프로그래밍 실습' 카테고리의 다른 글
[C# 실습,통신 제어] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.13 |
---|---|
[C# 실습,공장 UI 구현] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.12 |
[C# 실습,설비 컨트롤 예광탄] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습,예광탄] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습, 시나리오] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습] 레코드 코팅 - 기계 구현(Windows Forms) (0) | 2020.10.07 |
[C# 실습, 사용자 정의 컨트롤 제작 예광탄] 레코드 코팅 (0) | 2020.10.06 |
[C# 실습] 레코드 코팅 - 더블 버퍼링 가능한 Panel 정의하기 (0) | 2020.10.06 |
[C# 실습, 예광탄 소스] 레코드 코팅 (0) | 2020.10.06 |
[C# 실습 시나리오] 레코드 코팅 - 반도체 장비 및 제어시스템 개발자 양성 과정 (0) | 2020.10.06 |