ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Windows.Input;
using System.Collections.ObjectModel;
using TCP_Client.Model;
using WPF_Default;
using System.Windows;
using System.Windows.Forms;
namespace TCP_Client.ViewModel
{
class ClientViewModel : Notifier
{
NetworkStream networkStream;
private MessageModel selectedItem;
private string ip;
private string port;
private string content;
private int exportFileNum = 0;
private uint syncNum = 1234567890;
private bool isCheck = false;
private bool canConnect = true;
Thread thread;
public ICommand startCommand { get; set; }
public ICommand sendCommand { get; set; }
public ICommand deleteContextCommand { get; set; }
public ICommand exportContextCommand { get; set; }
public ICommand openMessageCommand { get; set; }
public ICommand systemExitCommand { get; set; }
private ObservableCollection<MessageModel> messageCollection;
private string connectText;
public ClientViewModel()
{
messageCollection = new ObservableCollection<MessageModel>();
startCommand = new Command(Start, canexecuteMethod);
sendCommand = new Command(Send, canexecuteMethod);
deleteContextCommand = new Command(DeleteContextMenu, canexecuteMethod);
exportContextCommand = new Command(ExportContextMenu, canexecuteMethod);
openMessageCommand = new Command(OpenMessageCommand, canexecuteMethod);
systemExitCommand = new Command(SystemExit, canexecuteMethod);
IP = "192.168.2.59";
Port = "3000";
ConnectText = "Connect";
}
#region ButtonMethode
private void Start(object obj)
{
if (canConnect)
{
thread = new Thread(Connect);
thread.IsBackground = true;
thread.Start();
canConnect = false;
}
else
{
thread.Abort();
canConnect = true;
MessageCollection.Add(new MessageModel() { Content = "연결 종료...", IP = this.IP, Time = DateTime.Now.ToString("F") });
}
if (ConnectText == "Connect")
ConnectText = "Dis connect";
else
ConnectText = "Connect";
}
private void Connect()
{
{
TcpClient tcpClient = new TcpClient();
try
{
IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(IP), int.Parse(Port));
Console.WriteLine("Try");
tcpClient.Connect(iPEnd);
canConnect = false;
}
catch (Exception e)
{
System.Windows.MessageBox.Show("IP 주소를 확인하시오.", "연결 실패 \n" + e);
ConnectText = "ReConnect";
return;
}
App.Current.Dispatcher.Invoke(() =>
{
MessageCollection.Add(new MessageModel() { Content = "연결 성공...", IP = this.IP, Time = DateTime.Now.ToString("F") });
});
networkStream = tcpClient.GetStream();
while (tcpClient.Connected)
{
Console.WriteLine("메시지");
byte[] headerArr = new byte[8];
if (networkStream.CanRead)
networkStream.Read(headerArr, 0, 8);
MessageModel messageModel = new MessageModel();
if (messageModel.CompareHeader(networkStream, headerArr, syncNum))
GenerateMessage(messageModel.Content);
}
}
}
public void GenerateMessage(string text)
{
Console.WriteLine(text);
App.Current.Dispatcher.Invoke(() =>
{
MessageCollection.Add(new MessageModel() { Content = text, IP = this.IP, Time = DateTime.Now.ToString("F") });
});
}
private void Send(object obj)
{
if (canConnect)
return;
Console.WriteLine("전송");
byte[] header = new byte[8];
byte[] sync = new byte[4];
byte[] type = new byte[2];
byte[] length = new byte[2];
sync = BitConverter.GetBytes((uint)syncNum);
;
if (IsCheck)
type[1] = 1;
else
type[1] = 0;
length[1] = (byte)Content.Length;
MessageModel messageModel = new MessageModel() { SyncPattern = sync, Type = type, Length = length, Content = this.Content, IP = this.IP, Time = DateTime.Now.ToString("F") };
MessageCollection.Add(messageModel);
messageModel.GeneratePacket();
networkStream.Write(messageModel.Packet, 0, messageModel.Packet.Length);
Console.WriteLine(messageModel.Packet);
}
private bool canexecuteMethod(object arg)
{
return true;
}
private void OpenMessageCommand(object obj)
{
string path;
string saveLine = "";
OpenFileDialog openBrowserDialog = new OpenFileDialog();
openBrowserDialog.Filter = "대화 (*.csv)|*.csv";
if (openBrowserDialog.ShowDialog() == DialogResult.OK)
{
path = openBrowserDialog.FileName;
StreamReader streamReader = new StreamReader(path, Encoding.GetEncoding("ks_c_5601-1987"));
while (saveLine != null)
{
saveLine = streamReader.ReadLine();
if (saveLine == null)
break;
GenerateMessage(saveLine, streamReader.ReadLine(), streamReader.ReadLine());
Console.WriteLine("데이터 읽어오는중...");
}
}
}
private void ExportContextMenu(object obj)
{
string path = "";
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
path = folderBrowserDialog.SelectedPath;
StreamWriter file = new StreamWriter(path + "/ExportData" + exportFileNum + ".csv", true, Encoding.GetEncoding("euc-kr"));
Console.WriteLine(path);
file.WriteLine(selectedItem.Time);
file.WriteLine(selectedItem.IP);
file.WriteLine(selectedItem.Content);
file.Flush();
file.Close();
}
}
private void DeleteContextMenu(object obj)
{
Console.WriteLine("DeleteContextMenu Clicked");
messageCollection.Remove(selectedItem);
}
public void SystemExit(object obj)
{
Environment.Exit(0);
}
#endregion
#region Getter&Setter
public ObservableCollection<MessageModel> MessageCollection
{
get { return messageCollection; }
set { messageCollection = value; }
}
public string IP
{
get { return ip; }
set { ip = value; OnPropertyChanged("IP"); }
}
public string Port
{
get { return port; }
set { port = value; OnPropertyChanged("Port"); }
}
public string Content
{
get { return content; }
set { content = value; OnPropertyChanged("Content"); }
}
public MessageModel SelectedItem
{
get { return selectedItem; }
set { selectedItem = value; OnPropertyChanged("SelectedItemNum"); Console.WriteLine(selectedItem); }
}
public string ConnectText
{
get { return connectText; }
set { connectText = value; OnPropertyChanged("ConnectText"); }
}
public bool IsCheck
{
get { return isCheck; }
set { isCheck = value; OnPropertyChanged("IsCheck"); }
}
#endregion
public void GenerateMessage(string date, string ip, string text)
{
MessageCollection.Add(new MessageModel() { Content = text, IP = ip, Time = date });
}
}
}
View (xaml)
<Window x:Class="TCP_Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TCP_Client.ViewModel"
mc:Ignorable="d"
WindowStyle="None" AllowsTransparency="False"
MouseDown="Window_MouseDown"
Title="Client" Height="500" Width="550"
Background="#FF002970"
>
<Window.DataContext>
<local:ClientViewModel/>
</Window.DataContext>
<Window.Resources>
<Style x:Key="ec" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="#FFF90000"/>
<Ellipse Fill="#FFF90000"
Margin="0,0,10,10"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="42"/>
<RowDefinition Height="380*"/>
<RowDefinition Height="47*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="#FF06003E">
<TextBlock Text="Client" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Lucida Bright" FontWeight="Bold" Foreground="Gold" />
</Grid>
<Grid Grid.Column="1" Grid.ColumnSpan="4" Background="#FF06003E">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
<Button Content="-" Width="20" Height="20" Click="Button_Click" Background="Gold" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,10,0" />
<Button Content="X" Width="20" Height="20" Click="Button_Click" Background="Gold" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,10,0" Command="{Binding systemExitCommand}" />
</StackPanel>
</Grid>
<Grid Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" >
<TextBlock Text="IP" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gold" FontFamily="Lucida Bright" />
</Grid>
<Grid Grid.Column="1" Grid.Row="1">
<TextBox Text="{Binding IP}" IsReadOnly="True" Height="20" VerticalAlignment="Center" Background="#FF4F6B9B"/>
</Grid>
<Grid Grid.Column="2" Grid.Row="1">
<TextBlock Text="Port" FontSize="20" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gold" FontFamily="Lucida Bright" />
</Grid>
<Grid Grid.Column="3" Grid.Row="1">
<TextBox Text="{Binding Port}" Height="20" Background="#FF4F6B9B"/>
</Grid>
<Grid Grid.Column="4" Grid.Row="1">
<Button Command="{Binding startCommand}" Background="AliceBlue" Content="{Binding ConnectText}" HorizontalAlignment="Center" Height="20" />
</Grid>
<Grid Grid.Row=" 2" Grid.ColumnSpan="5">
<DataGrid SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding MessageCollection}" AutoGenerateColumns="False" CanUserAddRows="False" Margin="10" Background="#FFA19FAE" >
<DataGrid.Columns>
<DataGridTextColumn Header="Time" Binding="{Binding Time}" IsReadOnly="True"/>
<DataGridTextColumn Header="Client" Binding="{Binding IP}" IsReadOnly="True"/>
<DataGridTextColumn Header="Message" Binding="{Binding Content}" IsReadOnly="True" Width="*" />
</DataGrid.Columns>
<DataGrid.ContextMenu >
<ContextMenu Name="GridContext" >
<MenuItem Header="Delete" Command="{Binding deleteContextCommand}"/>
<MenuItem Header="Export" Command="{Binding exportContextCommand}"/>
<MenuItem Header="Import" Command="{Binding openMessageCommand}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
<Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4">
<TextBox Text="{Binding Content}" HorizontalAlignment="Stretch" Height="30" Margin="10" Background="#FF4F6B9B"/>
</Grid>
<Grid Grid.Row="3" Grid.Column="4">
<StackPanel Orientation="Horizontal" Margin="-10,0,0,0">
<CheckBox IsChecked="{Binding IsCheck}" Content="Error" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,16,5,16" Foreground="Red" />
<Button Command="{Binding sendCommand}" Content="Send" Height="30" />
</StackPanel>
</Grid>
</Grid>
</Window>
Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace TCP_Client.Model
{
public class MessageModel
{
private byte[] packet;
private byte[] syncPatter;
private byte[] type;
private byte[] length;
private byte[] footer;
public byte[] Packet { get => packet; set => packet = value; }
public byte[] SyncPattern { get => syncPatter; set => syncPatter = value; }
public byte[] Type { get => type; set => type = value; }
public byte[] Length { get => length; set => length = value; }
public string Content { get; set; }
public string Time { get; set; }
public string IP { get; set; }
public byte[] Footer { get => footer; set => footer = value; }
public MessageModel()
{
packet = new byte[8];
syncPatter = new byte[4];
type = new byte[2];
length = new byte[2];
}
public byte[] GeneratePacket()
{
byte[] header = syncPatter.Concat(Type).Concat(Length).ToArray();
byte[] body = Encoding.UTF8.GetBytes(Content);
footer = new byte[header.Length];
footer = Enumerable.Reverse(header).ToArray();
Packet = header.Concat(body).Concat(footer).ToArray();
return Packet;
}
public bool CompareHeader(NetworkStream network, byte[] header, uint syncNum)
{
byte[] syncArr = new byte[4];
syncArr = header.Take(4).ToArray();
uint sync;
sync = BitConverter.ToUInt32(syncArr, 0);
if (sync == syncNum)
{
if (header[5] == 0)
Content = "정상: ";
else
Content = "오류: ";
int length = header[7];
byte[] contentArr = new byte[length];
network.Read(contentArr, 0, length);
byte[] footerArr = new byte[8];
network.Read(footerArr, 0, 8);
Content += Encoding.UTF8.GetString(contentArr);
return true;
}
else
{
MessageBox.Show("SyncPattern이 일치하지않음..");
return false;
}
}
}
}