using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace TestServer
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// TCP 리스너
/// </summary>
private TcpListener tcpListener;
/// <summary>
/// TCP 클라이언트
/// </summary>
private TcpClient tcpClient;
/// <summary>
/// 네트워크 스트림
/// </summary>
private NetworkStream networkStream;
/// <summary>
/// 스트림 라이터
/// </summary>
private StreamWriter streamWriter;
/// <summary>
/// 서버 작업 여부
/// </summary>
private bool isServerWorking = false;
/// <summary>
/// 스레드
/// </summary>
private Thread thread;
/// <summary>
/// 트리플 DES 암호 서비스 공급자
/// </summary>
private TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider();
/// <summary>
/// 개인 키 바이트 배열
/// </summary>
private byte[] privateKeyByteArray = new byte[]
{
98 , 45 , 125, 56, 1 , 60 , 11, 38 ,
123, 54 , 234, 9 , 76, 20 , 44, 7 ,
12 , 223, 219, 95, 48, 156, 32, 239
};
/// <summary>
/// 개인 키 초기 값 바이트 배열
/// </summary>
private byte[] privateKeyInitialValueByteArray = new byte[]
{
67, 12, 3, 41, 66, 78, 34, 123
};
/// <summary>
/// 난수기
/// </summary>
Random random = new Random();
/// <summary>
/// 임의 값
/// </summary>
private int randomValue = 0;
/// <summary>
/// 임의 개인 키 바이트 배열
/// </summary>
private byte[] randomPrivateKeyByteArray = null;
/// <summary>
/// 임의 개인 키 초기 값 바이트 배열
/// </summary>
private byte[] randomPrivateKeyInitialValueByteArray = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
#region 이벤트를 설정한다.
this.Load += Form_Load;
this.FormClosing += Form_FormClosing;
this.sendButton.Click += sendButton_Click;
this.timer.Tick += timer_Tick;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e"></param>
private void Form_Load(object sender, EventArgs e)
{
this.isServerWorking = true;
IPAddress ipAddress = new IPAddress(0);
this.tcpListener = new TcpListener(ipAddress, 2014);
this.tcpListener.Start();
this.thread = new Thread(StartServer);
this.thread.Start();
this.timer.Enabled = true;
this.randomValue = this.random.Next(1, 9);
SetRandomPrivateKeyByteArray(this.randomValue);
}
#endregion
#region 폼을 닫을 경우 처리하기 - Form_FormClosing(sender, e)
/// <summary>
/// 폼을 닫을 경우 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
if(!(this.streamWriter == null))
{
try
{
this.streamWriter.WriteLine(Encrypt("서버를 종료합니다."));
this.streamWriter.Flush();
}
catch { }
}
this.isServerWorking = false;
this.timer.Enabled = false;
if(!(this.streamWriter == null))
{
this.streamWriter.Close();
}
if(!(this.networkStream == null))
{
this.networkStream.Close();
}
if(!(this.tcpClient == null))
{
this.tcpClient.Close();
}
if(!(this.tcpListener == null))
{
this.tcpListener.Stop();
}
if(!(this.thread == null))
{
this.thread.Abort();
}
Application.ExitThread();
}
#endregion
#region 송신 버튼 클릭시 처리하기 - sendButton_Click(sender, e)
/// <summary>
/// 송신 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void sendButton_Click(object sender, EventArgs e)
{
if(this.networkStream != null && this.streamWriter != null)
{
this.streamWriter.WriteLine(Encrypt("12345abcde"));
this.streamWriter.Flush();
}
}
#endregion
#region 타이머 틱 처리하기 - timer_Tick(sender, e)
/// <summary>
/// 타이머 틱 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void timer_Tick(object sender, EventArgs e)
{
SendTimeMessage();
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 임의 개인 키 바이트 배열 설정하기 - SetRandomPrivateKeyByteArray(randomValue)
/// <summary>
/// 임의 개인 키 바이트 배열 설정하기
/// </summary>
/// <param name="randomValue">임의 값</param>
private void SetRandomPrivateKeyByteArray(int randomValue)
{
randomPrivateKeyByteArray = new byte[this.privateKeyByteArray.Length];
randomPrivateKeyInitialValueByteArray = new byte[this.privateKeyInitialValueByteArray.Length];
for(int i = 0; i < this.privateKeyByteArray.Length; i++)
{
int value = (int)this.privateKeyByteArray[i];
randomPrivateKeyByteArray[i] = Convert.ToByte(value / randomValue);
}
for(int i = 0; i < this.privateKeyInitialValueByteArray.Length; i++)
{
int value = (int)this.privateKeyInitialValueByteArray[i];
randomPrivateKeyInitialValueByteArray[i] = Convert.ToByte(value / randomValue);
}
}
#endregion
#region 메시지 박스 데이터 추가하기 - AddMessageTextBoxData(text)
/// <summary>
/// 메시지 박스 데이터 추가하기
/// </summary>
/// <param name="text">텍스트</param>
private void AddMessageTextBoxData(string text)
{
this.messageTextBox.AppendText(text + "\r\n");
this.messageTextBox.Focus();
this.messageTextBox.ScrollToCaret();
}
#endregion
#region 서버 시작하기 - StartServer()
/// <summary>
/// 서버 시작하기
/// </summary>
private void StartServer()
{
AddMessageTextBoxData("서버가 실행이 되었습니다.");
while(this.isServerWorking)
{
try
{
this.tcpClient = this.tcpListener.AcceptTcpClient();
AddMessageTextBoxData("클라이언트가 접속하였습니다.");
this.networkStream = this.tcpClient.GetStream();
this.streamWriter = new StreamWriter(this.networkStream);
}
catch
{
}
}
}
#endregion
#region 시간 메시지 송신하기 - SendTimeMessage()
/// <summary>
/// 시간 메시지 송신하기
/// </summary>
private void SendTimeMessage()
{
try
{
string messageEncrypted = Encrypt(Convert.ToString(DateTime.Now));
this.streamWriter.WriteLine(messageEncrypted);
this.streamWriter.Flush();
}
catch
{
}
}
#endregion
#region 암호화 하기 - Encrypt(message)
/// <summary>
/// 암호화 하기
/// </summary>
/// <param name="message">메시지</param>
/// <returns>암호화 메시지</returns>
private string Encrypt(string message)
{
string messageEncrypted = null;
byte[] textByteArray = UTF8Encoding.UTF8.GetBytes(message);
messageEncrypted = Convert.ToBase64String
(
this.tripleDESCryptoServiceProvider.CreateEncryptor
(
randomPrivateKeyByteArray,
randomPrivateKeyInitialValueByteArray
).TransformFinalBlock(textByteArray, 0, textByteArray.Length)
);
textByteArray = UTF8Encoding.UTF8.GetBytes(this.randomValue.ToString() + messageEncrypted);
messageEncrypted = Convert.ToBase64String
(
this.tripleDESCryptoServiceProvider.CreateEncryptor
(
this.privateKeyByteArray,
this.privateKeyInitialValueByteArray
).TransformFinalBlock(textByteArray, 0, textByteArray.Length)
);
return messageEncrypted;
}
#endregion
}
}