update basic form

main
syneffort 3 years ago
parent 300aadb23a
commit 758c943301
  1. 49
      SocketStudy/ClientForm/MainForm.Designer.cs
  2. 65
      SocketStudy/ClientForm/MainForm.cs
  3. 94
      SocketStudy/PComm/PClient.cs
  4. 3
      SocketStudy/PComm/PClientInfo.cs
  5. 1
      SocketStudy/PComm/PComm.csproj
  6. 19
      SocketStudy/PComm/PDataType.cs
  7. 73
      SocketStudy/PComm/PServer.cs
  8. 6
      SocketStudy/PObject/PObject.csproj
  9. 45
      SocketStudy/PUtil/PUtil.cs
  10. 1
      SocketStudy/PUtil/PUtility.csproj
  11. 65
      SocketStudy/ServerForm/ChildForm/ImageForm.Designer.cs
  12. 34
      SocketStudy/ServerForm/ChildForm/ImageForm.cs
  13. 120
      SocketStudy/ServerForm/ChildForm/ImageForm.resx
  14. 59
      SocketStudy/ServerForm/DataManager.cs
  15. 21
      SocketStudy/ServerForm/ServerForm.csproj
  16. 19
      SocketStudy/ServerForm/mainForm.Designer.cs
  17. 84
      SocketStudy/ServerForm/mainForm.cs

@ -30,7 +30,9 @@ namespace ClientForm
private void InitializeComponent() private void InitializeComponent()
{ {
this.logConsole = new System.Windows.Forms.TextBox(); this.logConsole = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button(); this.stringButton = new System.Windows.Forms.Button();
this.objectButton = new System.Windows.Forms.Button();
this.imageButton = new System.Windows.Forms.Button();
this.SuspendLayout(); this.SuspendLayout();
// //
// logConsole // logConsole
@ -41,25 +43,48 @@ namespace ClientForm
this.logConsole.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.logConsole.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.logConsole.Multiline = true; this.logConsole.Multiline = true;
this.logConsole.Name = "logConsole"; this.logConsole.Name = "logConsole";
this.logConsole.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.logConsole.Size = new System.Drawing.Size(470, 344); this.logConsole.Size = new System.Drawing.Size(470, 344);
this.logConsole.TabIndex = 1; this.logConsole.TabIndex = 1;
// //
// button1 // stringButton
// //
this.button1.Location = new System.Drawing.Point(177, 35); this.stringButton.Location = new System.Drawing.Point(34, 39);
this.button1.Name = "button1"; this.stringButton.Name = "stringButton";
this.button1.Size = new System.Drawing.Size(75, 23); this.stringButton.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 2; this.stringButton.TabIndex = 2;
this.button1.Text = "button1"; this.stringButton.Text = "string";
this.button1.UseVisualStyleBackColor = true; this.stringButton.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click); this.stringButton.Click += new System.EventHandler(this.stringButton_Click);
//
// objectButton
//
this.objectButton.Location = new System.Drawing.Point(146, 39);
this.objectButton.Name = "objectButton";
this.objectButton.Size = new System.Drawing.Size(75, 23);
this.objectButton.TabIndex = 2;
this.objectButton.Text = "object";
this.objectButton.UseVisualStyleBackColor = true;
this.objectButton.Click += new System.EventHandler(this.objectButton_Click);
//
// imageButton
//
this.imageButton.Location = new System.Drawing.Point(268, 39);
this.imageButton.Name = "imageButton";
this.imageButton.Size = new System.Drawing.Size(75, 23);
this.imageButton.TabIndex = 2;
this.imageButton.Text = "image";
this.imageButton.UseVisualStyleBackColor = true;
this.imageButton.Click += new System.EventHandler(this.imageButton_Click);
// //
// MainForm // MainForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(498, 450); this.ClientSize = new System.Drawing.Size(498, 450);
this.Controls.Add(this.button1); this.Controls.Add(this.imageButton);
this.Controls.Add(this.objectButton);
this.Controls.Add(this.stringButton);
this.Controls.Add(this.logConsole); this.Controls.Add(this.logConsole);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "MainForm"; this.Name = "MainForm";
@ -72,7 +97,9 @@ namespace ClientForm
#endregion #endregion
private System.Windows.Forms.TextBox logConsole; private System.Windows.Forms.TextBox logConsole;
private System.Windows.Forms.Button button1; private System.Windows.Forms.Button stringButton;
private System.Windows.Forms.Button objectButton;
private System.Windows.Forms.Button imageButton;
} }
} }

@ -9,6 +9,7 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -20,6 +21,7 @@ namespace ClientForm
private PClient client; private PClient client;
private System.Timers.Timer heartBeatTimer; private System.Timers.Timer heartBeatTimer;
private System.Timers.Timer testTimer;
public MainForm() public MainForm()
{ {
@ -29,18 +31,25 @@ namespace ClientForm
private void InitInstance() private void InitInstance()
{ {
heartBeatClient = new PClient("127.0.0.1", 7778); string clientId = PUtil.GetRandomString(5);
string heartBeatClientId = clientId + "_hb";
heartBeatClient = new PClient("127.0.0.1", 7778, heartBeatClientId);
heartBeatClient.OnReceived += HeartBeatClient_OnReceived; heartBeatClient.OnReceived += HeartBeatClient_OnReceived;
client = new PClient("127.0.0.1", 7777); client = new PClient("127.0.0.1", 7777, clientId);
client.OnReceived += Client_OnReceived; client.OnReceived += Client_OnReceived;
heartBeatTimer = new System.Timers.Timer(); heartBeatTimer = new System.Timers.Timer();
heartBeatTimer.Interval = 5000; heartBeatTimer.Interval = 5000;
heartBeatTimer.Elapsed += HeartBeatTimer_Elapsed; heartBeatTimer.Elapsed += HeartBeatTimer_Elapsed;
heartBeatTimer.Start(); heartBeatTimer.Start();
}
testTimer = new System.Timers.Timer();
testTimer.Interval = 500;
testTimer.Elapsed += TestTimer_Elapsed;
testTimer.Start();
}
private void WriteLog(string log) private void WriteLog(string log)
{ {
@ -51,42 +60,68 @@ namespace ClientForm
else else
{ {
logConsole.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}] {log}" + Environment.NewLine); logConsole.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}] {log}" + Environment.NewLine);
PUtil.ScrollToEnd(logConsole); //PUtil.ScrollToEnd(logConsole);
} }
} }
private void HeartBeatTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) private void HeartBeatTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{ {
heartBeatClient.Send("heartbeat"); heartBeatClient.Send(PServer.HB_CHECK);
} }
private void HeartBeatClient_OnReceived(PClient sender, byte[] data) private void HeartBeatClient_OnReceived(PClient sender, PDataType dataType, byte[] data)
{ {
string msg = Encoding.UTF8.GetString(data, 0, data.Length); if (dataType != PDataType.SimpleString)
if (msg != "good")
{ {
msg = "WARNING!!! BAD HEARTBEAT!!!"; WriteLog("ERROR!!! WRONG DATA TYPE FOR HEART BEAT!!!");
return;
} }
WriteLog(msg); string msg = Encoding.UTF8.GetString(data, 0, data.Length);
if (msg != PServer.HB_CHECK)
WriteLog("WARNING!!! BAD HEARTBEAT!!!");
} }
private void Client_OnReceived(PClient sender, byte[] data) private void Client_OnReceived(PClient sender, PDataType dataType, byte[] data)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private void button1_Click(object sender, EventArgs e) private void TestTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//button1_Click(sender, e);
}
private void stringButton_Click(object sender, EventArgs e)
{ {
client.Send("String send test!");
}
private void objectButton_Click(object sender, EventArgs e)
{
Random rand = new Random();
Person person = new Person() Person person = new Person()
{ {
Name = "Kim", Name = PUtil.GetRandomString(5),
Age = 35 Age = rand.Next(20, 100)
}; };
byte[] data = PSerializer.Serialize(person); byte[] data = PSerializer.Serialize(person);
client.Send(data); client.Send(PDataType.Person, data);
}
private void imageButton_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "JPG File|*.jpg|PNG File|*.png|All File|*.*";
if (dlg.ShowDialog() == DialogResult.Cancel)
return;
Image img = Image.FromFile(dlg.FileName);
byte[] data = PUtil.ImageToByteArray(img);
client.Send(PDataType.Image, data);
GC.Collect();
} }
} }
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
@ -13,13 +14,13 @@ namespace PComm
{ {
private readonly int BUFF_SIZE = 8192; private readonly int BUFF_SIZE = 8192;
public delegate void ClientReceivedHandler(PClient sender, byte[] data); public delegate void ClientReceivedHandler(PClient sender, PDataType dataType, byte[] data);
public event ClientReceivedHandler OnReceived; public event ClientReceivedHandler OnReceived;
public delegate void ClientDisconnectedHandler(PClient sender); public delegate void ClientDisconnectedHandler(PClient sender);
public event ClientDisconnectedHandler Disconnected; public event ClientDisconnectedHandler Disconnected;
public string ID { get; private set; } public string ID { get; set; }
public IPEndPoint EndPoint { get; private set; } public IPEndPoint EndPoint { get; private set; }
@ -27,33 +28,49 @@ namespace PComm
private Socket socket; private Socket socket;
public PClient(string ip, int port) public PClient(string ip, int port, string id = null)
{ {
if (string.IsNullOrEmpty(id))
id = Guid.NewGuid().ToString();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.ID = Guid.NewGuid().ToString(); this.ID = id;
this.EndPoint = new IPEndPoint(IPAddress.Parse(ip), port); this.EndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Connect(EndPoint); socket.Connect(EndPoint);
// send ID
this.Send(PDataType.ClientID, Encoding.UTF8.GetBytes(this.ID));
socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null); socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null);
} }
public PClient(Socket accepted) public PClient(Socket accepted)
{ {
if (string.IsNullOrEmpty(this.ID))
this.ID = Guid.NewGuid().ToString();
socket = accepted; socket = accepted;
this.ID = Guid.NewGuid().ToString();
this.EndPoint = (IPEndPoint)socket.RemoteEndPoint; this.EndPoint = (IPEndPoint)socket.RemoteEndPoint;
socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null); socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null);
} }
public int Send(string msg) public int Send(string msg)
{ {
byte[] buff = Encoding.UTF8.GetBytes(msg); socket.Send(BitConverter.GetBytes((int)PDataType.SimpleString), 0, 4, 0);
return socket.Send(buff, SocketFlags.None); byte[] data = Encoding.UTF8.GetBytes(msg);
byte[] length = BitConverter.GetBytes(data.Length);
socket.Send(length, 0, 4, 0);
return socket.Send(data, SocketFlags.None);
} }
public int Send(byte[] msg) public int Send(PDataType dataType, byte[] data)
{ {
return socket.Send(msg, SocketFlags.None); socket.Send(BitConverter.GetBytes((int)dataType), 0, 4, 0);
byte[] length = BitConverter.GetBytes(data.Length);
socket.Send(length, 0, 4, 0);
return socket.Send(data, SocketFlags.None);
} }
private void AcceptCallback(IAsyncResult ar) private void AcceptCallback(IAsyncResult ar)
@ -62,25 +79,58 @@ namespace PComm
{ {
socket.EndReceive(ar); socket.EndReceive(ar);
byte[] buff = new byte[BUFF_SIZE]; // get data type
byte[] dataTypeBuff = new byte[4];
socket.Receive(dataTypeBuff, dataTypeBuff.Length, SocketFlags.None);
PDataType dataType = (PDataType)BitConverter.ToInt32(dataTypeBuff, 0);
int receiveSize = socket.Receive(buff, buff.Length, SocketFlags.None); // get data size
if (receiveSize <= 0) byte[] sizeBuff = new byte[4];
{ socket.Receive(sizeBuff, sizeBuff.Length, SocketFlags.None);
Close(); int dataSize = BitConverter.ToInt32(sizeBuff, 0);
if (Disconnected != null) using (MemoryStream ms = new MemoryStream())
Disconnected(this);
}
else if (receiveSize < buff.Length)
{ {
Array.Resize<byte>(ref buff, receiveSize); while (dataSize > 0)
} {
byte[] buff;
if (dataSize < BUFF_SIZE)
buff = new byte[dataSize];
else
buff = new byte[BUFF_SIZE];
if (OnReceived != null) int receiveSize = socket.Receive(buff, buff.Length, SocketFlags.None);
OnReceived(this, buff);
ms.Write(buff, 0, buff.Length);
dataSize -= receiveSize;
}
byte[] data = ms.ToArray();
if (OnReceived != null)
OnReceived(this, dataType, data);
}
socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null); socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null);
//byte[] buff = new byte[BUFF_SIZE];
//int receiveSize = socket.Receive(buff, buff.Length, SocketFlags.None);
//if (receiveSize <= 0)
//{
// Close();
// if (Disconnected != null)
// Disconnected(this);
//}
//else if (receiveSize < buff.Length)
//{
// Array.Resize<byte>(ref buff, receiveSize);
//}
//if (OnReceived != null)
// OnReceived(this, buff);
//socket.BeginReceive(new byte[] { 0 }, 0, 0, 0, AcceptCallback, null);
} }
catch (Exception ex) catch (Exception ex)
{ {

@ -9,7 +9,8 @@ namespace PComm
public class PClientInfo public class PClientInfo
{ {
public PClient Client { get; set; } public PClient Client { get; set; }
public string LastMessage { get; set; } public PDataType LastDataType { get; set; }
public byte[] LastData { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public DateTime LastReceivedAt { get; set; } public DateTime LastReceivedAt { get; set; }
} }

@ -43,6 +43,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="PClient.cs" /> <Compile Include="PClient.cs" />
<Compile Include="PClientInfo.cs" /> <Compile Include="PClientInfo.cs" />
<Compile Include="PDataType.cs" />
<Compile Include="PListener.cs" /> <Compile Include="PListener.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PServer.cs" /> <Compile Include="PServer.cs" />

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PComm
{
public enum PDataType
{
ClientID = 0,
SimpleString = 10,
Person = 100,
Image = 200,
}
}

@ -10,7 +10,9 @@ namespace PComm
{ {
public class PServer public class PServer
{ {
public delegate void ClientDataReceivedHandler(PClientInfo sender, byte[] data); public static readonly string HB_CHECK = "OK";
public delegate void ClientDataReceivedHandler(PClientInfo sender, PDataType dataType, byte[] data);
public event ClientDataReceivedHandler OnDataReceived; public event ClientDataReceivedHandler OnDataReceived;
private PListener listener; private PListener listener;
@ -41,44 +43,62 @@ namespace PComm
private void Listener_SocketAccepted(object sender, SocketAcceptedEventArgs e) private void Listener_SocketAccepted(object sender, SocketAcceptedEventArgs e)
{ {
PClient client = new PClient(e.Accepted); PClient client = new PClient(e.Accepted);
client.OnReceived += Client_Received; client.OnReceived += Client_OnReceived;
client.Disconnected += Client_Disconnected; client.Disconnected += Client_Disconnected;
Debug.WriteLine($"Client accepted: {client.ID} @ { DateTime.Now}"); Debug.WriteLine($"[{ DateTime.Now}] Temp client accepted: {client.ID}");
} }
private void Client_Disconnected(PClient sender) private void Client_OnReceived(PClient sender, PDataType dataType, byte[] data)
{
if (clientInfoDict.ContainsKey(sender.ID))
{
lock (garbageLock)
{
clientInfoDict.Remove(sender.ID);
}
}
}
private void Client_Received(PClient sender, byte[] data)
{ {
lock (garbageLock) lock (garbageLock)
{ {
if (!clientInfoDict.ContainsKey(sender.ID)) if (!clientInfoDict.ContainsKey(sender.ID))
clientInfoDict.Add(sender.ID, new PClientInfo()); clientInfoDict.Add(sender.ID, new PClientInfo());
}
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
clientInfoDict[sender.ID].Client = sender; clientInfoDict[sender.ID].Client = sender;
clientInfoDict[sender.ID].CreatedAt = now; clientInfoDict[sender.ID].CreatedAt = now;
clientInfoDict[sender.ID].LastReceivedAt = now; clientInfoDict[sender.ID].LastReceivedAt = now;
}
string msg = Encoding.UTF8.GetString(data); clientInfoDict[sender.ID].LastDataType = dataType;
clientInfoDict[sender.ID].LastMessage = msg; clientInfoDict[sender.ID].LastData = data;
// check client id
if (dataType == PDataType.ClientID)
{
string clientId = Encoding.UTF8.GetString(data, 0, data.Length);
clientInfoDict.Add(clientId, clientInfoDict[sender.ID]);
lock (garbageLock)
{
if (clientInfoDict.ContainsKey(sender.ID))
clientInfoDict.Remove(sender.ID);
}
sender.ID = clientId;
Debug.WriteLine($"[{ DateTime.Now}] client accepted: {sender.ID}");
return;
}
if (OnDataReceived != null && clientInfoDict.ContainsKey(sender.ID)) if (OnDataReceived != null && clientInfoDict.ContainsKey(sender.ID))
OnDataReceived(clientInfoDict[sender.ID], data); OnDataReceived(clientInfoDict[sender.ID], dataType, data);
Debug.WriteLine(($"Client message({sender.ID}): {msg} @ { DateTime.Now}")); Debug.WriteLine(($"[{ DateTime.Now}] Client message({sender.ID}): {dataType.ToString()}({data.Length})"));
}
private void Client_Disconnected(PClient sender)
{
if (clientInfoDict.ContainsKey(sender.ID))
{
lock (garbageLock)
{
clientInfoDict.Remove(sender.ID);
}
}
} }
private void GarbageTimer_Elapsed(object sender, ElapsedEventArgs e) private void GarbageTimer_Elapsed(object sender, ElapsedEventArgs e)
@ -95,5 +115,10 @@ namespace PComm
clientInfoDict.Remove(key); clientInfoDict.Remove(key);
} }
} }
public List<PClientInfo> ClientInfoList
{
get { return clientInfoDict.Values.ToList(); }
}
} }
} }

@ -45,5 +45,11 @@
<Compile Include="PSerializer.cs" /> <Compile Include="PSerializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PComm\PComm.csproj">
<Project>{A88648B7-3EAE-4BFF-B5EF-2FED447C7B9C}</Project>
<Name>PComm</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

@ -1,14 +1,31 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms; using System.Windows.Forms;
namespace PUtility namespace PUtility
{ {
public class PUtil public class PUtil
{ {
private static readonly string characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
public static string GetRandomString(int length = 5)
{
char[] randCharArr = new char[length];
Random rand = new Random();
for (int i = 0; i < length; i++)
{
randCharArr[i] = characters[rand.Next(characters.Length)];
}
return new string(randCharArr);
}
public static void ScrollToEnd(TextBox target) public static void ScrollToEnd(TextBox target)
{ {
if (target == null) if (target == null)
@ -17,5 +34,31 @@ namespace PUtility
target.SelectionStart = target.Text.Length; target.SelectionStart = target.Text.Length;
target.ScrollToCaret(); target.ScrollToCaret();
} }
}
public static byte[] ImageToByteArray(Image image)
{
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, image.RawFormat);
return ms.ToArray();
}
}
public static Bitmap ByteToImage(byte[] imgByteArray)
{
using (MemoryStream ms = new MemoryStream(imgByteArray))
{
Bitmap img = Image.FromStream(ms) as Bitmap;
return img;
}
}
public static void SaveImage(string fileName, Image img, ImageFormat format)
{
using (Image saveImage = new Bitmap(img))
{
saveImage.Save(fileName, format);
}
}
}
} }

@ -33,6 +33,7 @@
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />

@ -0,0 +1,65 @@

namespace ServerForm.ChildForm
{
partial class ImageForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.SuspendLayout();
//
// pictureBox
//
this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox.Location = new System.Drawing.Point(0, 0);
this.pictureBox.Name = "pictureBox";
this.pictureBox.Size = new System.Drawing.Size(545, 505);
this.pictureBox.TabIndex = 0;
this.pictureBox.TabStop = false;
//
// ImageForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(545, 505);
this.Controls.Add(this.pictureBox);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.Name = "ImageForm";
this.Text = "Image";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ImageForm_FormClosed);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox;
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ServerForm.ChildForm
{
public partial class ImageForm : Form
{
private string filePath;
public ImageForm(Image image)
{
InitializeComponent();
InitInstance(image);
}
private void InitInstance(Image image)
{
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox.Image = image;
}
private void ImageForm_FormClosed(object sender, FormClosedEventArgs e)
{
GC.Collect();
}
}
}

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -0,0 +1,59 @@
using PComm;
using PObject;
using PUtility;
using ServerForm.ChildForm;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ServerForm
{
class DataManager
{
public static DataManager Instance { get; private set; } = new DataManager();
public void Process(PClientInfo clientInfo, PDataType dataType, byte[] data, LogHandler logHandler, FormHandler formHandler)
{
string log = "";
switch (dataType)
{
case PDataType.ClientID:
log = Encoding.UTF8.GetString(data, 0, data.Length);
logHandler(clientInfo.Client, log);
break;
case PDataType.SimpleString:
log = Encoding.UTF8.GetString(data, 0, data.Length);
logHandler(clientInfo.Client, log);
break;
case PDataType.Person:
Person person = PSerializer.Deserialize<Person>(data);
log = $"Name: {person.Name}, Age: {person.Age}";
logHandler(clientInfo.Client, log);
break;
case PDataType.Image:
Image image = PUtil.ByteToImage(data);
//string fileName = $@"{System.IO.Path.GetTempPath()}{Guid.NewGuid()}.bmp";
//PUtil.SaveImage(fileName, image, image.RawFormat);
log = $"Receive {data.Length.ToString("#,###")}bytes image";
logHandler(clientInfo.Client, log);
ImageForm imgForm = new ImageForm(image);
formHandler(imgForm);
GC.Collect();
break;
default:
logHandler(clientInfo.Client, "ERROR!!! UNEXPECTED DATA TYPE!!!");
break;
}
}
}
}

@ -46,16 +46,26 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="mainForm.cs"> <Compile Include="DataManager.cs" />
<Compile Include="ChildForm\ImageForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
<Compile Include="mainForm.Designer.cs"> <Compile Include="ChildForm\ImageForm.Designer.cs">
<DependentUpon>mainForm.cs</DependentUpon> <DependentUpon>ImageForm.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="mainForm.resx"> <EmbeddedResource Include="ChildForm\ImageForm.resx">
<DependentUpon>mainForm.cs</DependentUpon> <DependentUpon>ImageForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
@ -93,5 +103,6 @@
<Name>PUtility</Name> <Name>PUtility</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

@ -30,24 +30,36 @@ namespace ServerForm
private void InitializeComponent() private void InitializeComponent()
{ {
this.logConsole = new System.Windows.Forms.TextBox(); this.logConsole = new System.Windows.Forms.TextBox();
this.clientListBox = new System.Windows.Forms.ListBox();
this.SuspendLayout(); this.SuspendLayout();
// //
// logConsole // logConsole
// //
this.logConsole.BackColor = System.Drawing.Color.Black; this.logConsole.BackColor = System.Drawing.Color.Black;
this.logConsole.ForeColor = System.Drawing.Color.SpringGreen; this.logConsole.ForeColor = System.Drawing.Color.SpringGreen;
this.logConsole.Location = new System.Drawing.Point(12, 13); this.logConsole.Location = new System.Drawing.Point(251, 13);
this.logConsole.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.logConsole.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.logConsole.Multiline = true; this.logConsole.Multiline = true;
this.logConsole.Name = "logConsole"; this.logConsole.Name = "logConsole";
this.logConsole.Size = new System.Drawing.Size(470, 344); this.logConsole.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.logConsole.Size = new System.Drawing.Size(470, 364);
this.logConsole.TabIndex = 0; this.logConsole.TabIndex = 0;
// //
// clientListBox
//
this.clientListBox.FormattingEnabled = true;
this.clientListBox.ItemHeight = 15;
this.clientListBox.Location = new System.Drawing.Point(12, 13);
this.clientListBox.Name = "clientListBox";
this.clientListBox.Size = new System.Drawing.Size(233, 364);
this.clientListBox.TabIndex = 2;
//
// MainForm // MainForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(493, 368); this.ClientSize = new System.Drawing.Size(733, 390);
this.Controls.Add(this.clientListBox);
this.Controls.Add(this.logConsole); this.Controls.Add(this.logConsole);
this.Font = new System.Drawing.Font("맑은 고딕", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); this.Font = new System.Drawing.Font("맑은 고딕", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
@ -62,6 +74,7 @@ namespace ServerForm
#endregion #endregion
private System.Windows.Forms.TextBox logConsole; private System.Windows.Forms.TextBox logConsole;
private System.Windows.Forms.ListBox clientListBox;
} }
} }

@ -1,6 +1,7 @@
using PComm; using PComm;
using PObject; using PObject;
using PUtility; using PUtility;
using ServerForm.ChildForm;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
@ -13,16 +14,22 @@ using System.Windows.Forms;
namespace ServerForm namespace ServerForm
{ {
delegate void LogHandler(PClient client, string log);
delegate void FormHandler(Form form);
public partial class MainForm : Form public partial class MainForm : Form
{ {
private readonly int PORT = 7777; private readonly int PORT = 7777;
private readonly int HB_PORT = 7778; private readonly int HB_PORT = 7778;
private readonly string HB_MSG = "good";
private PServer mainServer; private PServer mainServer;
private PServer heartBeatServer; private PServer heartBeatServer;
private LogHandler logHandler;
private FormHandler formHandler;
private System.Timers.Timer clientCheckTimer;
public MainForm() public MainForm()
{ {
InitializeComponent(); InitializeComponent();
@ -37,37 +44,90 @@ namespace ServerForm
heartBeatServer.OnDataReceived += HeartBeatServer_OnDataReceived; heartBeatServer.OnDataReceived += HeartBeatServer_OnDataReceived;
mainServer.OnDataReceived += MainServer_OnDataReceived; mainServer.OnDataReceived += MainServer_OnDataReceived;
logHandler = new LogHandler(WriteLog);
formHandler = new FormHandler(ShowForm);
heartBeatServer.Start(); heartBeatServer.Start();
mainServer.Start(); mainServer.Start();
clientCheckTimer = new System.Timers.Timer();
clientCheckTimer.Interval = 1000;
clientCheckTimer.Elapsed += ClientCheckTimer_Elapsed;
clientCheckTimer.Start();
}
private void WriteLog(PClient client, string log)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate () { WriteLog(client, log); });
}
else
{
logConsole.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}] {client.ID}: {log}" + Environment.NewLine);
//PUtil.ScrollToEnd(logConsole);
}
} }
private void WriteLog(string log) private void ShowForm(Form form)
{ {
if (this.InvokeRequired) if (this.InvokeRequired)
{ {
Invoke((MethodInvoker)delegate () { WriteLog(log); }); this.Invoke((MethodInvoker)delegate () { ShowForm(form); });
} }
else else
{ {
logConsole.AppendText($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}] {log}" + Environment.NewLine); form.Show();
PUtil.ScrollToEnd(logConsole);
} }
} }
private void MainServer_OnDataReceived(PClientInfo sender, byte[] data) private void CheckClientInfo(List<PClientInfo> clinetInfoList)
{ {
Person person = PSerializer.Deserialize<Person>(data); if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate () { CheckClientInfo(clinetInfoList); });
}
else
{
if (clientListBox.Items != null && clientListBox.Items.Count > 1)
clientListBox.Items.Clear();
WriteLog($"Name: {person.Name}, Age: {person.Age}"); foreach (PClientInfo clientInfo in clinetInfoList)
{
PClient client = clientInfo.Client;
string clientView = $"{client.ID}({client.EndPoint.Address}:{client.EndPoint.Port})";
clientListBox.Items.Add(clientView);
}
}
} }
private void HeartBeatServer_OnDataReceived(PClientInfo sender, byte[] data) private void MainServer_OnDataReceived(PClientInfo sender, PDataType dataType, byte[] data)
{ {
DataManager.Instance.Process(sender, dataType, data, logHandler, formHandler);
}
private void HeartBeatServer_OnDataReceived(PClientInfo sender, PDataType dataType, byte[] data)
{
if (dataType != PDataType.SimpleString)
{
logHandler(sender.Client, "ERROR!!! WRONG DATA TYPE FOR HEART BEAT!!!");
return;
}
string msg = Encoding.UTF8.GetString(data, 0, data.Length); string msg = Encoding.UTF8.GetString(data, 0, data.Length);
if (msg != PServer.HB_CHECK)
logHandler(sender.Client, "WARNING!!! BAD HEARTBEAT!!!");
WriteLog(msg); sender.Client.Send(PServer.HB_CHECK);
}
private void ClientCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
List<PClientInfo> clientInfoList = new List<PClientInfo>(mainServer.ClientInfoList.Count + heartBeatServer.ClientInfoList.Count);
clientInfoList.AddRange(mainServer.ClientInfoList);
clientInfoList.AddRange(heartBeatServer.ClientInfoList);
sender.Client.Send(HB_MSG); CheckClientInfo(clientInfoList);
} }
} }
} }

Loading…
Cancel
Save