ChatGPT)
C#에서 public string SpecificPay { get; set; }와 public string SpecificPay;의 차이는 다음과 같습니다:

1. public string SpecificPay { get; set; }

public string SpecificPay { get; set; }: 이것은 C#의 속성(Property)입니다. 속성은 클래스의 멤버로, 해당 속성에 대한 값을 캡슐화하고, 접근을 제어하며, 필요한 경우 추가 로직을 적용할 수 있습니다. 이 특정 속성은 읽기 및 쓰기가 가능합니다(getter와 setter 모두가 존재함).

2. public string SpecificPay;

public string SpecificPay;: 이것은 클래스의 필드(Field)입니다. 필드는 해당 클래스의 인스턴스마다 각각의 값을 저장합니다. 이것은 간단한 데이터 저장 용도로 사용되며, 특별한 접근 로직이나 제한이 없습니다. 직접적으로 필드에 접근하여 값을 설정하거나 가져올 수 있습니다.


따라서, 첫 번째 선언은 읽기 및 쓰기가 가능한 속성을 정의하고, 두 번째 선언은 클래스의 필드를 정의합니다.

 

 

TCP 증권데이타 수신및 송신의 원리를 위의 그림을 보면서 설명한다.

1. TCP증권데이타는 한국거래소에서 계약되어진 회원사에 일방적으로 전송한다.
2. 회원사는 A,B,C라고 3개로 예를 든다.
3. 회원사 A,B,C는 수신받는 엔진을 보일러로 표시하고 보일러로 설명해 본다.
4. 회원사는 A,B,C는 집의 규모가 틀리다. 물론 보일러도 처리용량에 차이가 있다. 좋은 보일러, 혹은 그외.
5. TCP증권데이타를 물로 예를들면, 물을 공급해서 A,B,C가 보일러로 처리하는 도중에 보일러에 문제가 생기면한국거래소에서는 물공급을 중단한다. 그리고 해당 회원사에 통보한다.
6. 계속 입수되는 물을 보일러에서 잘 처리되도록 회원사는 A,B,C는 보일러를 각각 잘 관리해야 한다.

Practice)
20,000 바이트를 보낸다면, 각각 회원사는 A,B,C는 할당되어진 버퍼만큼 받을수 있다.
A - 10,000 + 10,000 = 20,000 두번에 걸쳐서 받는다.
B - 5,000 + 5,000 + 5,000 + 5,000 = 20,000 네번에 걸쳐서 받는다.
C - 20,000 한번에 받는다.

20,000 바이트에는 보내는 데이타종류가 15개가 들어있다고 치자.(체결,호가등등)
A - 10,000 + 10,000 = 20,000 두번에 걸쳐서 받이서 데이타종류가 15개를 추출해야 한다.
B - 5,000 + 5,000 + 5,000 + 5,000 = 20,000 네번에 걸쳐서 받이서 데이타종류가 15개를 추출해야 한다.
C - 20,000 한번에 받이서 데이타종류가 15개를 추출해야 한다.

결국 회원사는 A,B,C는 관으로 표현하자면, 넓은 관을 통해서 받던지, 좁은 관을 통해서 받던지, 결국은 받아서 데이타종류가 15개를 추출해야 한다.

결과화면)


(CHAT.GPT)
WPF에서 메인 윈도우에서 클래스를 호출하고, 해당 클래스에서 다이얼로그를 메인 윈도우의 가운데에 위치하도록 호출하려면, 다음과 같은 절차를 따르면 됩니다.

  1. 메인 윈도우에서 클래스 호출
  2. 클래스에서 다이얼로그 호출 시 메인 윈도우를 기준으로 위치 설정



1. MainWindow.xaml.cs

메인 윈도우에서 클래스를 호출하는 버튼 클릭 이벤트를 설정합니다.

using System.Windows;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenDialogFromClassButton_Click(object sender, RoutedEventArgs e)
        {
            DialogHelper helper = new DialogHelper();
            helper.ShowDialog(this);
        }
    }
}

2. DialogHelper.cs

다이얼로그를 표시할 클래스입니다.

using System.Windows;

namespace WpfApp
{
    public class DialogHelper
    {
        public void ShowDialog(Window owner)
        {
            DialogWindow dialog = new DialogWindow
            {
                Owner = owner,
                WindowStartupLocation = WindowStartupLocation.CenterOwner
            };
            dialog.ShowDialog();
        }
    }
}

3. DialogWindow.xaml

다이얼로그 윈도우의 XAML 파일입니다.

<Window x:Class="WpfApp.DialogWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DialogWindow"
        Height="200"
        Width="400">
    <Grid>
        <!-- 다이얼로그의 UI 요소들 -->
    </Grid>
</Window>

4. DialogWindow.xaml.cs

다이얼로그 윈도우의 코드 비하인드 파일입니다.

using System.Windows;

namespace WpfApp
{
    public partial class DialogWindow : Window
    {
        public DialogWindow()
        {
            InitializeComponent();
        }
    }
}

5. MainWindow.xaml

메인 윈도우의 XAML 파일에서 클래스를 호출하여 다이얼로그를 여는 버튼을 추가합니다.

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Grid>
        <Button Content="Open Dialog from Class" Click="OpenDialogFromClassButton_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

요약

이 구조에서는 DialogHelper 클래스가 메인 윈도우의 인스턴스를 인자로 받아 다이얼로그를 중앙에 위치하도록 설정합니다. 이렇게 하면 다이얼로그 윈도우가 항상 메인 윈도우의 중앙에 표시됩니다.






아래검색파일에서 Value="14"를 Value="10"으로 변경하고자, 구글링하려고 했으나, (CHAT.GPT)를 이용하니, 바로 리눅스명령어 알려줌
아래검색파일에서 Value="14"를 Value="10"으로 변경하고자, 구글링하려고 했으나, (CHAT.GPT)를 이용하니, 바로 리눅스명령어 알려줌


xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/WindowsPresenFoundation/WINPAYCalcM
$ find ./ -name "*.xaml" | xargs grep FontSize | grep Value=
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="14"/>
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="14"/>
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="14"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="14"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="14"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="14"/>
./MainWindow.xaml:            <Setter Property="FontSize" Value="10"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="14"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="14"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="14"/>

xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/WindowsPresenFoundation/WINPAYCalcM
$ sed -i 's/Value="10"/Value="11"/g' ./BasicInfoDialog.xaml ./FileListNM.xaml ./SpecificDialog.xaml

xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/WindowsPresenFoundation/WINPAYCalcM
$ find ./ -name "*.xaml" | xargs grep FontSize | grep Value=
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="10"/>
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="10"/>
./BasicInfoDialog.xaml:            <Setter Property="FontSize" Value="10"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="10"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="10"/>
./FileListNM.xaml:        <Setter Property="FontSize" Value="10"/>
./MainWindow.xaml:            <Setter Property="FontSize" Value="10"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="10"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="10"/>
./SpecificDialog.xaml:        <Setter Property="FontSize" Value="10"/>

xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/WindowsPresenFoundation/WINPAYCalcM
$

 

접속표준서(TCP) 공통정보(송신채널_정보구분)

 

접속표준서(TCP) 공통정보(송신채널_정보구분)
1.
- 그룹별로 3,4개의 포트로 구성됨.
- 수신사는(예를 들어 네이버, 팍스넷, 싱크풀등등) 데이타를 수신하는 서버프로그램을 작성해야 한다.


2.
- 보통 포트별로 한개의 서버가 1:1로 통신하는 방식을 취한다.
- 한번 맺은 세션은 끊어지지 않는다. 즉 하나의 포트를 담당하는 수신서버는 Accept를 한번 하는 꼴이다.
- 한번 맺은 세션은 끊어지지 않는다. Accept후에 데이타를 수신해서 데이타를 파싱하는 로직이 들어가면 된다.
- 한번 맺은 세션은 끊어지지 않는다. Accept후에 데이타를 수신하는 과정에서, 패킷은 헤더와 테일은 존재하지 않는다.
- 한번 맺은 세션은 끊어지지 않는다. Accept후에 데이타를 수신하는 과정에서, 데이타를 구분짓는 구분자 0xff만 존재
- 구체적으로 10,000바이트를 받았다면 여러개의 정보데이타를 끊어서 저장해야한다.
- 정보데이타의 길이정보를 이용해서 수신받는 데이타를 분리한다면, 제도변경시에 좋지 않는 방법이다.
- Ack가 없는 관계의 TCP 수신,송신방법이다.
- 송신하는쪽도 일방적으로 데이타를 보낸다. 수신하는쪽이 잘 받았는지 못받았는지는 신경쓰지 않는다.
(마치 UDP처럼)
- 수신하는쪽도 송신하는쪽에 Ack신호를 보내지 않는다. 무조건 데이타를 받기만한다.
- 만약에 수신쪽의 서버나 네트웍이 불안해서 송신데이타를 보내는쪽에서 프로그램이 죽는다면, ㅠㅠㅠㅠ(?)
- 만약에 수신쪽의 서버나 네트웍이 불안해서 송신데이타를 보내는쪽에서 프로그램이 죽는다면, ㅠㅠㅠㅠ(?)
- 만약에 수신쪽의 서버나 네트웍이 불안해서 송신데이타를 보내는쪽에서 프로그램이 죽는다면, ㅠㅠㅠㅠ(?)
(절대 그렇게 설계를 해서는 안되지만, 장애로 분리되겠다.)

- UDP는 송신쪽에서 보내기만 할뿐, 수신쪽과 상관없기떄문에, 송신쪽 프로그램이 죽는경우는 발생하지 않는다.
(즉 수신쪽의 프로그램의 정상여부를 알수가 없다. 하지만 TCP는 알수 있기떄문에 통보해줄수 있다.)


3.
- 구분해서 분리되어진 정보데이타패킷은 저장하는 방법으로 여러가지가 있을것이다.(메모리,디비,메모리디비,파일등등)
- netstat -an | grep Listen 으로 명령어를 실행하면 수신 포트갯수만큼 나올것이다.
- netstat -an | grep ESTABLISHED 으로 명령어를 실행하면 수신 포트갯수만큼 나올것이다.


A301S        G140KR7395400005001491150011499628200000000005000000050000000000003000000049950000000503000000004970000000169022000000000844538870.0001000000000000000000000       0502000000005000 0xff
A301S        G140KR7018250001000603150011505463200000001050000000230500000000002000000222000000002370000000021450000000348867000000007940610250.0001000000000000000000000       2325000000023050 0xff
A301S        G140KR7042670000000710150011509142500000000280000000091000000000022000000093800000000940000000009070000003129543000000028712498060.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7010130003000492150011516616500000011000000005450000000000001000005560000000055600000000542000000000040379000000022063218000.0001000000000000000000005       4600000000545000 0xff
A301S        G140KR7074610007000767150011516845500000001580000000142100000000070000000162500000001630000000014170000011525661000000171499537320.0002000000000000000000000       1421000000014200 0xff
A301S        G140KR7042670000000710150011519030500000000280000000091000000000007000000093800000000940000000009070000003129550000000028712561760.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7015260003000574150011521442200000000060000000024800000000001000000024250000000260000000002310000002374822000000005909336090.0001000000000000000000000       0249000000002480 0xff
A301S        G140KR7005070008000344150011521734500000000900000001828000000000001000001840000000018600000000176000000000445860000000080994328200.0002000000000000000000001       8280000000182700 0xff
A301S        G140KR7042670000000710150011529108500000000280000000091000000000006000000093800000000940000000009070000003129556000000028712616360.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7285130001001229150011534317500000000600000000781000000000028000000781000000007870000000076800000000074168000000005762897800.0001000000000000000000000       7820000000078100 0xff
A301S        G140KR7018670000000607150011534410500000000500000001208000000000001000001217000000012170000000118800000000007102000000000849499600.0002000000000000000000001       2080000000120700 0xff
A301S        G140KR7042670000000710150011539763500000000280000000091000000000007000000093800000000940000000009070000003129563000000028712680060.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7069260008000748150011545434200000000550000000235000000000037000000230500000002415000000022800000000472597000000011151020750.0001000000000000000000000       2355000000023450 0xff
A301S        G140KR7285130001001229150011545707500000000600000000781000000000016000000781000000007870000000076800000000074184000000005764147400.0001000000000000000000000       7820000000078100 0xff
A301S        G140KR7323410001001332150011549230500000000150000000236500000000001000000238500000002400000000023500000001015103000000024082797850.0002000000000000000000000       2365000000023600 0xff
A301S        G140KR7042670000000710150011549573500000000280000000091000000000032000000093800000000940000000009070000003129595000000028712971260.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7025820002000645150011558337200000000190000000054500000000001000000054100000000553000000005060000007489311000000039879368230.0001000000000000000000000       0546000000005450 0xff
A301S        G140KR7042670000000710150011560718500000000280000000091000000000015000000093800000000940000000009070000003129610000000028713107760.0001000000000000000000000       0911000000009100 0xff
A301S        G140KR7042670000000710150011572588500000000280000000091000000000020000000093800000000940000000009070000003129630000000028713289760.0001000000000000000000000       0911000000009100 0xff

 

1. 기존 Windows Form방식)
- 기존 Form방식에서 사용되어진 Form 화면디자인을 WPF방식에는 이용할수 없다는점이 아쉽다.
- Form과 WPF를 동시에 코딩을 원한다면, 화면과 로직을 분리하는 설계를 잘해야한다.
- 즉 Form Class에 로직코드에 해당되는 부분은 클래스파일을 따로 만들어서 작성하도록 한다.

2. Windows.Presentation.Foundation(WPF) 방식
- 디자인파트
- 코드파트로 나눌수 있다는점에서 웹프로그래밍과 일맥상통하다.(xaml/cs)

FiancialCalc.msi
0.71MB


<Window x:Class="WINPAYCalcM.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:WINPAYCalcM"
        mc:Ignorable="d"
        Title="원리금균등상환계산기(대출상환포함)" Height="1000" Width="1400"
KeyDown="Window_KeyDown">
    <Window.Resources>
        <Style TargetType="DataGrid">
            <Setter Property="ColumnHeaderHeight" Value="40"/>
            <Setter Property="RowHeight" Value="30"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="HorizontalGridLinesBrush" Value="LightGray"/>
            <Setter Property="VerticalGridLinesBrush" Value="LightGray"/>
            <Setter Property="AlternatingRowBackground" Value="LightCyan"/>
            <Setter Property="Background" Value="White"/>
        </Style>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Background" Value="SlateGray"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
        <Style TargetType="DataGridRow">
            <EventSetter Event="MouseEnter" Handler="DataGridRow_MouseEnter"/>
            <EventSetter Event="MouseLeave" Handler="DataGridRow_MouseLeave"/>
            <Setter Property="Background" Value="White"/>
        </Style>
    </Window.Resources>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Information">
                <MenuItem Header="기초정보입력" Click="BasicInfoMenuItem_Click"/>
                <MenuItem Header="상환정보입력(자동)" Click="RepayMenuItem_Click"/>
                <MenuItem Header="상환정보입력(수동)" Click="RepayManualMenuItem_Click"/>
                <Separator/>
                <MenuItem Header="_Exit" Click="ExitMenuItem_Click"/>
            </MenuItem>
            <MenuItem Header="_File">
                <MenuItem Header="_Save" Click="SaveFileMenuItem_Click"/>
                <MenuItem Header="_Open" Click="OpenFileMenuItem_Click"/>
            </MenuItem>
            <MenuItem Header="_Help">
                <MenuItem Header="_About" Click="AboutMenuItem_Click"/>
            </MenuItem>
        </Menu>
        <!-- 다른 컨텐츠 -->
        <Grid>
            <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" IsReadOnly="False" CanUserAddRows="True"
                  CanUserDeleteRows="True" CanUserResizeColumns="True" CanUserSortColumns="True" Margin="10">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="번호" Binding="{Binding index}" Width="*"/>
                    <DataGridTextColumn Header="상환방법" Binding="{Binding repaymethod}" Width="*"/>
                    <DataGridTextColumn Header="날짜" Binding="{Binding date}" Width="*"/>
                    <DataGridTextColumn Header="이자금액" Binding="{Binding rate_real_to_bank}" Width="*"/>
                    <DataGridTextColumn Header="원금금액" Binding="{Binding reapy_real_to_bank}" Width="*"/>
                    <DataGridTextColumn Header="이자상환합계" Binding="{Binding rate_real_to_bank_sum}" Width="*"/>
                    <DataGridTextColumn Header="현재원금" Binding="{Binding remain_original_pay}" Width="*"/>
    <DataGridTextColumn Header="원리금균등상환금액(일정)" Binding="{Binding original_rent_pay}" Width="*"/>
                    <DataGridTextColumn Header="이자+원금합계" Binding="{Binding calc_pricipal_plus_interest_sum}" Width="*"/>
                    <DataGridTextColumn Header="상환금액합계(원금+매달일정상환)" Binding="{Binding remain_repay_except_interest_sum}" Width="*"/>
                </DataGrid.Columns>

            </DataGrid>
        </Grid>
    </DockPanel>
</Window>

FTP로 파일을 전송 시 아스키(ASCII) 모드와 바이너리(Binary) 모드 두 가지가 있습니다. 
아스키 모드로 전송하는 경우 수신 컴퓨터에서 파일을 읽지 못하는 문제가 발생할 수 있습니다. 
ftp로 전송했는데 파일에 문제가 있다면 혹시 아스키 모드로 보냈는지 확인해보세요.

FTP 전송 모드
바이너리 모드로 보내야 하는 경우
바이너리 모드는 파일을 0과 1로 구성된 원시 데이터로 전송하는 모드입니다. 
가공되지 않은 원본 데이터이기 때문에 발송자가 보내는 파일과 수신자가 받는 파일이 정확히 같습니다.

반드시 바이너리 모드로 전송해야만 하는 파일들이 존재합니다. 
이미지 파일(.jpg, bmp, png), 사운드 파일(.mp3, .avi, .wma), 비디오 파일(.flv, .mkv, .mov, .mp4), 아카이브 파일(.zip, .rar, .tar), 그 외 실행 및 문서 파일(.exe, .doc, .xls, .pdf) 등이 그렇습니다. 사실 이렇게 나열할 필요도 없고 텍스트 형식이 아니면 그냥 바이너리로 보내야 한다고 보시면 됩니다.

아스키 모드 사용 이유
아스키 모드는 파일을 텍스트로 전송할 때 사용되는 모드입니다. 
ASCII는 American Standard Code for Information Interchange의 약자입니다. 정보 교환을 위해 만든 미국의 표준 코드입니다. .txt, html, .php, .cgi, .js, .txt, .css 등 확장자를 보낼 때 아스키 모드가 권고되기도 합니다.
당연하게도 텍스트 파일 역시 바이너리로 전송해도 됩니다. 
다만 아스키 모드로 전송 시 CR(Carriage Return)이 제거된다는 장점(?)이 있습니다. 
이게 무슨 말이냐 하면, 운영체제 간 행바꿈을 표현하는 기호의 차이를 보정해준다는 것입니다.

굳이 아스키 모드 안 써도 되는 이유
그럼에도 아스키 모드는 현재로서 영향력을 잃어가는 추세입니다. 
왜냐하면 바이너리 모드로도 별 문제가 없기 때문입니다. 
위에서 언급한 형식의 문제는 이미 상용 프로그램들이 스스로 보정을 해주기 때문입니다.
게다가 아스키 모드는 한국어, 일본어, 중국어 등의 문자를 처리하지 못합니다. 
텍스트 파일이라 할지라도 한글로 쓴 문서는 어차피 바이너리로 보내야 합니다.
이런 흐름을 반영하듯 sftp에선 모든 데이터는 바이너리 모드로 전송됩니다. 아스키 모드는 없습니다. 

비고)
윈도우는 띄어쓰기를 하면 캐리지 리턴(CR)과 라인피드(LF)가 모두 표기됩니다. 
두 용어는 과거 타자기에서 유래된 용어인데, 그게 중요한 건 아니고 결과적으로 아래의 예시 같은 차이가 발생한다는 것만 이해하시면 됩니다.
윈도우의 경우 줄을 바꾸면 \r\n
이렇게 \r\n 둘이 표시됩니다.
리눅스, 맥, FreeBSD, AIX 등 유닉스 시스템의 경우 줄을 바꾸면 \n
이렇게 \n만 표시됩니다.
그러니 윈도우에서 작성한 텍스트 파일을 리눅스에 보낼 때 아스키 모드는 CR(\n)을 제거해 차이를 보정해주기 때문에 이점이 있습니다.

클로바 AI에게 물어본결과)
FTP(File Transfer Protocol)는 파일 전송을 위한 프로토콜로, ASCII와 Binary 모드를 구분하여 사용합니다.
ASCII 모드: 텍스트 파일 전송에 사용되며, 각 문자를 7비트의 ASCII 코드로 변환하여 전송합니다. 전송 과정에서 데이터의 손실이나 변형이 일어날 가능성이 적습니다.
Binary 모드: 이미지, 동영상, 압축 파일 등의 바이너리 파일 전송에 사용되며, 파일의 원래 형태를 그대로 유지하여 전송합니다.
모드의 선택은 전송할 파일의 종류와 특성에 따라 달라집니다. 이를 고려하여 적절한 모드를 선택해야 합니다.

 

TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/
TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/
TCP의 흐름 제어/Ack/Console/Multi File Send/Recv/Thread/Windows/

 

SEND(Console)

send.cs
0.01MB

 

RECV(Console)

recv.cs
0.01MB

TCP(Transmission Control Protocol)은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.
만약 TCP가 이런 기능들을 제공해주지 않는다면 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에 TCP가 제공해주는 이러한 기능들 덕분에 우리는 온전히 상위 레이어의 동작에만 집중할 수 있는 것이다.
보통 TCP의 전송 제어 방법은 전송되는 데이터의 양을 조절하는 흐름 제어, 통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법인 오류 제어, 네트워크 혼잡에 대처하는 혼잡 제어로 나누어진다.
물론 TCP 같은 전송 계층의 프로토콜을 어플리케이션 레이어에서 활동하는 개발자가 건드릴 일은 많이 없다. 그러나 혹시라도 이 부분에서 뭔가 문제가 발생했을 경우, TCP가 어떤 식으로 작동하는지 모른다면 고치는 건 둘째치고 원인 파악조차 하지 못하는 슬픈 상황이 발생할 수 있으므로 여러모로 알아두는 것이 좋다고 생각한다. (더불어 야근도 따라올 것이다)
그런 의미에서 이번 포스팅에서는 TCP의 흐름 제어 기법들과 오류 제어 기법들에 대한 이야기를 한번 해보려고 한다.

TCP의 흐름 제어

송신 측과 수신 측이 서로 데이터를 주고 받을 때, 여러가지 요인에 따라 이 두 친구들의 처리 속도가 달라질 수 있다. 이때 데이터를 받는 수신 측의 처리 속도가 송신 측보다 빠른 경우는 사실 별 문제가 없다.
주는 족족 빠르게 처리해주니 딱히 문제될 것이 없는 것이다. 그러나 수신 측의 처리 속도보다 송신 측이 더 빠른 경우 문제가 생긴다.
송신 측과 수신 측은 모두 데이터를 저장할 수 있는 버퍼를 가지고 있다. 이때 수신 측이 자신의 버퍼 안에 있는 데이터를 처리하는 속도보다 송신 측이 데이터를 전송하는 속도가 더 빠르다면, 당연히 수신 측의 버퍼는 언젠가 꽉 차버릴 것이기 때문이다.
수신 측의 버퍼가 꽉 찬 상태에서 도착한 데이터는 더 이상 담아둘 공간이 없기 때문에 폐기 처분된다. 물론 이런 상황에서는 송신 측이 다시 데이터를 보내주기는 하겠지만, 데이터 전송이라는게 네트워크 환경에 따라 변수가 워낙 많은 작업이기 때문에 사실 이 작업을 줄일 수 있으면 줄이는 것이 가장 좋다.
그래서 송신 측은 수신 측의 데이터 처리 속도를 파악하고 자신이 얼마나 빠르게, 많은 데이터를 전송할 지 결정해야한다. 이것이 바로 TCP의 흐름 제어인 것이다.
수신 측은 자신이 처리할 수 있는 데이터의 양을 의미하는 윈도우 크기(Window Size)를 자신의 응답 헤더에 담아서 송신 측에게 전해주게 되고, 송신 측은 상대방에게 데이터를 보낼 때 이 윈도우 크기와 네트워크의 현재 상황을 참고해서 알맞은 양의 데이터를 보냄으로써 전체적인 데이터의 흐름을 제어하게 된다.

1. Stop and Wait
Stop and Wait 방식은 이름 그대로 상대방에게 데이터를 보낸 후 잘 받았다는 응답이 올 때까지 기다리는 모든 방식을 통칭하는 말이다. 이때 데이터를 받는 수신 측은 잘 받았어!와 못 받았어... 등의 대답을 해주게 되는데, 수신 측이 어떤 대답을 해주냐에 따라 사용할 수 있는 오류 제어 방법이 나눠지기도 한다.
Stop and Wait로 흐름 제어를 할 경우의 대원칙은 단순히 상대방이 응답을 하면 데이터를 보낸다이기 때문에 구현 자체도 간단하고 개발자가 어플리케이션의 작동 원리를 파악하기도 쉬운 편이다.
기본적인 ARQ(Automatic Repeat Request)를 구현한다고 생각해보면, 수신 측의 윈도우 크기를 1 byte로 설정하고 처리 가능 = 1, 처리 불가능 = 0과 같은 식으로 대충 구현해도 돌아가기는 하기 때문이다.
하지만 서로 처리 가능, 처리 불가능 정도의 의미만 주고받는 방식은 간단한만큼 비효율적이라고 할 수도 있다. 왜냐하면 송신 측은 자신이 직접 데이터를 보내봐야 이 데이터를 수신 측이 처리할 수 있는지 알 수 있기 때문이다. 쉽게 말해서 이런 기초적인 Stop and Wait 방식은 그냥 될 때까지 주구장창 보내는 방식이라고 봐도 무방하다.
그런 이유로 Stop and Wait 방식을 사용하여 흐름 제어를 할 경우에는, 이런 비효율성을 커버하기 위해 이런 단순한 구현이 아닌 여러가지 오류 제어 방식을 함께 도입해서 사용한다.

2. Sliding Window

방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

 

 

패킷의 흐름과 오류를 제어하는 TCP | Evans Library (evan-moon.github.io)

 

패킷의 흐름과 오류를 제어하는 TCP

은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.

evan-moon.github.io

 

 

 

TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/Ack/Stop and Wait>File Send/Recv/Windows/Guage/Thread/

Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.

TCP(Transmission Control Protocol)은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.
만약 TCP가 이런 기능들을 제공해주지 않는다면 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에 TCP가 제공해주는 이러한 기능들 덕분에 우리는 온전히 상위 레이어의 동작에만 집중할 수 있는 것이다.
보통 TCP의 전송 제어 방법은 전송되는 데이터의 양을 조절하는 흐름 제어, 통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법인 오류 제어, 네트워크 혼잡에 대처하는 혼잡 제어로 나누어진다.
물론 TCP 같은 전송 계층의 프로토콜을 어플리케이션 레이어에서 활동하는 개발자가 건드릴 일은 많이 없다. 그러나 혹시라도 이 부분에서 뭔가 문제가 발생했을 경우, TCP가 어떤 식으로 작동하는지 모른다면 고치는 건 둘째치고 원인 파악조차 하지 못하는 슬픈 상황이 발생할 수 있으므로 여러모로 알아두는 것이 좋다고 생각한다. (더불어 야근도 따라올 것이다)
그런 의미에서 이번 포스팅에서는 TCP의 흐름 제어 기법들과 오류 제어 기법들에 대한 이야기를 한번 해보려고 한다.

TCP의 흐름 제어

송신 측과 수신 측이 서로 데이터를 주고 받을 때, 여러가지 요인에 따라 이 두 친구들의 처리 속도가 달라질 수 있다. 이때 데이터를 받는 수신 측의 처리 속도가 송신 측보다 빠른 경우는 사실 별 문제가 없다.
주는 족족 빠르게 처리해주니 딱히 문제될 것이 없는 것이다. 그러나 수신 측의 처리 속도보다 송신 측이 더 빠른 경우 문제가 생긴다.
송신 측과 수신 측은 모두 데이터를 저장할 수 있는 버퍼를 가지고 있다. 이때 수신 측이 자신의 버퍼 안에 있는 데이터를 처리하는 속도보다 송신 측이 데이터를 전송하는 속도가 더 빠르다면, 당연히 수신 측의 버퍼는 언젠가 꽉 차버릴 것이기 때문이다.
수신 측의 버퍼가 꽉 찬 상태에서 도착한 데이터는 더 이상 담아둘 공간이 없기 때문에 폐기 처분된다. 물론 이런 상황에서는 송신 측이 다시 데이터를 보내주기는 하겠지만, 데이터 전송이라는게 네트워크 환경에 따라 변수가 워낙 많은 작업이기 때문에 사실 이 작업을 줄일 수 있으면 줄이는 것이 가장 좋다.
그래서 송신 측은 수신 측의 데이터 처리 속도를 파악하고 자신이 얼마나 빠르게, 많은 데이터를 전송할 지 결정해야한다. 이것이 바로 TCP의 흐름 제어인 것이다.
수신 측은 자신이 처리할 수 있는 데이터의 양을 의미하는 윈도우 크기(Window Size)를 자신의 응답 헤더에 담아서 송신 측에게 전해주게 되고, 송신 측은 상대방에게 데이터를 보낼 때 이 윈도우 크기와 네트워크의 현재 상황을 참고해서 알맞은 양의 데이터를 보냄으로써 전체적인 데이터의 흐름을 제어하게 된다.

1. Stop and Wait
Stop and Wait 방식은 이름 그대로 상대방에게 데이터를 보낸 후 잘 받았다는 응답이 올 때까지 기다리는 모든 방식을 통칭하는 말이다. 이때 데이터를 받는 수신 측은 잘 받았어!와 못 받았어... 등의 대답을 해주게 되는데, 수신 측이 어떤 대답을 해주냐에 따라 사용할 수 있는 오류 제어 방법이 나눠지기도 한다.
Stop and Wait로 흐름 제어를 할 경우의 대원칙은 단순히 상대방이 응답을 하면 데이터를 보낸다이기 때문에 구현 자체도 간단하고 개발자가 어플리케이션의 작동 원리를 파악하기도 쉬운 편이다.
기본적인 ARQ(Automatic Repeat Request)를 구현한다고 생각해보면, 수신 측의 윈도우 크기를 1 byte로 설정하고 처리 가능 = 1, 처리 불가능 = 0과 같은 식으로 대충 구현해도 돌아가기는 하기 때문이다.
하지만 서로 처리 가능, 처리 불가능 정도의 의미만 주고받는 방식은 간단한만큼 비효율적이라고 할 수도 있다. 왜냐하면 송신 측은 자신이 직접 데이터를 보내봐야 이 데이터를 수신 측이 처리할 수 있는지 알 수 있기 때문이다. 쉽게 말해서 이런 기초적인 Stop and Wait 방식은 그냥 될 때까지 주구장창 보내는 방식이라고 봐도 무방하다.
그런 이유로 Stop and Wait 방식을 사용하여 흐름 제어를 할 경우에는, 이런 비효율성을 커버하기 위해 이런 단순한 구현이 아닌 여러가지 오류 제어 방식을 함께 도입해서 사용한다.

 



>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)

while (true)
{
    while(true)
    {
        bytesSent = sender.Send(fileByte);
        bytesSent = sender.Receive(recvByte);

        string flagTxt = Encoding.UTF8.GetString(recvByte, 0, bytesSent);

        if (flagTxt == "no") continue;
        else if (flagTxt == "go") break;
    }
}

>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)

while (true)
{
    int sz = handler.Receive(bytes);

    if (sz == -1) break;
    else if (sz != PACKSZ) //제대로 받지를 못했다고 판단했을때에
    {
if (sz + cur < filesz) //실제로 마지막데이타도 아니라면
{
    handler.Send("no");
    continue;
}
    }

    cur += sz;

    handler.Send("go");

    if (cur > filesz) break;
    else if (filesz == cur) break;
}

 

TCP의 흐름 제어/Stop and Wait>File Recv/Windows/Guage/
TCP의 흐름 제어/Stop and Wait>File Recv/Windows/Guage/

Program.cs
0.00MB
ACKRcvFrm.cs
0.01MB
ACKRcvFrm.Designer.cs
0.06MB
AGauge.cs
0.06MB



TCP의 흐름 제어/ Stop and Wait>File Send/Windows/
TCP의 흐름 제어/ Stop and Wait>File Send/Windows/

 

ACKSndFrm.cs
0.01MB
ACKSndFrm.Designer.cs
0.00MB
Program.cs
0.00MB

TCP의 흐름 제어/No-Ack/Sliding Window/File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/No-Ack/Sliding Window/File Send/Recv/Windows/Guage/Thread/
TCP의 흐름 제어/No-Ack/Sliding Window/File Send/Recv/Windows/Guage/Thread/

1) Using Send Thread
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용시에 다중 데이타를 송신/수신할수 있다.
2) Using Send Basic class
Send하는 파트에서 Thread 활용을 안해도 다중 데이타를 송신/수신할수 있다.
Send하는 파트에서 Thread 활용을 안해도 다중 데이타를 송신/수신할수 있다.

TCP의 흐름 제어/Sliding Window

2. Sliding Window
방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

File Send/Recv/Guage12/Multi Socket Thread/
File Send/Recv/Guage12/Multi Socket Thread/

File Sender
When Enter Key Pressed,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1. file size sender
2. file name sender
3. file data sender

 

Program.cs
0.00MB
Form1.cs
0.01MB
Form1.Designer.cs
0.00MB



File Receiver
1. file size receive
2. file name receive( -> Rename: YYYYMMDDHHMISS_0000_filename)
3. file read receive(Guage display)


Program.cs
0.00MB
AGauge.cs
0.06MB
Form1.cs
0.01MB
Form1.Designer.cs
0.06MB

TCP의 흐름 제어/Sliding Window

2. Sliding Window
방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

File Recv/Send-Thread/ProgressBar(feat. Thread)

 

UAPDBMQ0010.Designer.cs
0.00MB
UAPDBMQ0010.cs
0.01MB
windows_frm_file_send.cs
0.00MB
windows_file_send.c
0.00MB

TCP의 흐름 제어/Sliding Window

2. Sliding Window
방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

File Send/Recv - Window form/Thread/Recv/

 

1. 파일사이즈 전송

2. 파일이름 전송

3. 파일데이타 전송

4. 수신받는 서버는 파일이름을 YYYYMMDDHHMISS_FILENAME으로 저장

windows_file_send.c
0.00MB
frm_win_file_recv.cs
0.01MB
frm_win_file_recv.Designer.cs
0.00MB
program.cs
0.00MB

file recv/send/delemeter(0x0d,0x0e,0xff)/멀티수신/windows src

1. 다중 클라이언트 파일 송신

2. 멀티수신서버

3. 수신방법은 delemeter(0x0d,0x0e,0xff) 사용

4. 파일명은 YYYYMMDDHHMISS_FILENAME으로 설정

 

windows_send_byte.c
0.00MB
windows_multi_recv_byte.cs
0.00MB

 

TCP(Transmission Control Protocol)은 원활한 통신을 위해 전송하는 데이터 흐름을 제어하고 네트워크의 혼잡 상태를 파악해서 대처하는 기능을 프로토콜 자체에 포함하고 있다.
만약 TCP가 이런 기능들을 제공해주지 않는다면 개발자가 일일히 데이터를 어떤 단위로 보낼 것인지 정의해야하고, 패킷이 유실되면 어떤 예외처리를 해야하는 지까지 신경써야하기 때문에 TCP가 제공해주는 이러한 기능들 덕분에 우리는 온전히 상위 레이어의 동작에만 집중할 수 있는 것이다.
보통 TCP의 전송 제어 방법은 전송되는 데이터의 양을 조절하는 흐름 제어, 통신 도중에 데이터가 유실되거나 잘못된 데이터가 수신되었을 경우 대처하는 방법인 오류 제어, 네트워크 혼잡에 대처하는 혼잡 제어로 나누어진다.
물론 TCP 같은 전송 계층의 프로토콜을 어플리케이션 레이어에서 활동하는 개발자가 건드릴 일은 많이 없다. 그러나 혹시라도 이 부분에서 뭔가 문제가 발생했을 경우, TCP가 어떤 식으로 작동하는지 모른다면 고치는 건 둘째치고 원인 파악조차 하지 못하는 슬픈 상황이 발생할 수 있으므로 여러모로 알아두는 것이 좋다고 생각한다. (더불어 야근도 따라올 것이다)
그런 의미에서 이번 포스팅에서는 TCP의 흐름 제어 기법들과 오류 제어 기법들에 대한 이야기를 한번 해보려고 한다.

TCP의 흐름 제어

송신 측과 수신 측이 서로 데이터를 주고 받을 때, 여러가지 요인에 따라 이 두 친구들의 처리 속도가 달라질 수 있다. 이때 데이터를 받는 수신 측의 처리 속도가 송신 측보다 빠른 경우는 사실 별 문제가 없다.
주는 족족 빠르게 처리해주니 딱히 문제될 것이 없는 것이다. 그러나 수신 측의 처리 속도보다 송신 측이 더 빠른 경우 문제가 생긴다.
송신 측과 수신 측은 모두 데이터를 저장할 수 있는 버퍼를 가지고 있다. 이때 수신 측이 자신의 버퍼 안에 있는 데이터를 처리하는 속도보다 송신 측이 데이터를 전송하는 속도가 더 빠르다면, 당연히 수신 측의 버퍼는 언젠가 꽉 차버릴 것이기 때문이다.
수신 측의 버퍼가 꽉 찬 상태에서 도착한 데이터는 더 이상 담아둘 공간이 없기 때문에 폐기 처분된다. 물론 이런 상황에서는 송신 측이 다시 데이터를 보내주기는 하겠지만, 데이터 전송이라는게 네트워크 환경에 따라 변수가 워낙 많은 작업이기 때문에 사실 이 작업을 줄일 수 있으면 줄이는 것이 가장 좋다.
그래서 송신 측은 수신 측의 데이터 처리 속도를 파악하고 자신이 얼마나 빠르게, 많은 데이터를 전송할 지 결정해야한다. 이것이 바로 TCP의 흐름 제어인 것이다.
수신 측은 자신이 처리할 수 있는 데이터의 양을 의미하는 윈도우 크기(Window Size)를 자신의 응답 헤더에 담아서 송신 측에게 전해주게 되고, 송신 측은 상대방에게 데이터를 보낼 때 이 윈도우 크기와 네트워크의 현재 상황을 참고해서 알맞은 양의 데이터를 보냄으로써 전체적인 데이터의 흐름을 제어하게 된다.

1. Stop and Wait
Stop and Wait 방식은 이름 그대로 상대방에게 데이터를 보낸 후 잘 받았다는 응답이 올 때까지 기다리는 모든 방식을 통칭하는 말이다. 이때 데이터를 받는 수신 측은 잘 받았어!와 못 받았어... 등의 대답을 해주게 되는데, 수신 측이 어떤 대답을 해주냐에 따라 사용할 수 있는 오류 제어 방법이 나눠지기도 한다.
Stop and Wait로 흐름 제어를 할 경우의 대원칙은 단순히 상대방이 응답을 하면 데이터를 보낸다이기 때문에 구현 자체도 간단하고 개발자가 어플리케이션의 작동 원리를 파악하기도 쉬운 편이다.
기본적인 ARQ(Automatic Repeat Request)를 구현한다고 생각해보면, 수신 측의 윈도우 크기를 1 byte로 설정하고 처리 가능 = 1, 처리 불가능 = 0과 같은 식으로 대충 구현해도 돌아가기는 하기 때문이다.
하지만 서로 처리 가능, 처리 불가능 정도의 의미만 주고받는 방식은 간단한만큼 비효율적이라고 할 수도 있다. 왜냐하면 송신 측은 자신이 직접 데이터를 보내봐야 이 데이터를 수신 측이 처리할 수 있는지 알 수 있기 때문이다. 쉽게 말해서 이런 기초적인 Stop and Wait 방식은 그냥 될 때까지 주구장창 보내는 방식이라고 봐도 무방하다.
그런 이유로 Stop and Wait 방식을 사용하여 흐름 제어를 할 경우에는, 이런 비효율성을 커버하기 위해 이런 단순한 구현이 아닌 여러가지 오류 제어 방식을 함께 도입해서 사용한다.

>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)
>>>>보내는쪽에서의 개략소스)

while (true)
{
    while(true)
    {
        bytesSent = sender.Send(fileByte);
        bytesSent = sender.Receive(recvByte);

        string flagTxt = Encoding.UTF8.GetString(recvByte, 0, bytesSent);

        if (flagTxt == "no") continue;
        else if (flagTxt == "go") break;
    }
}

>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)
>>>>받는쪽에서 개략소스)

while (true)
{
    int sz = handler.Receive(bytes);

    if (sz == -1) break;
    else if (sz != PACKSZ) //제대로 받지를 못했다고 판단했을때에
    {
if (sz + cur < filesz) //실제로 마지막데이타도 아니라면
{
    handler.Send("no");
    continue;
}
    }

    cur += sz;

    handler.Send("go");

    if (cur > filesz) break;
    else if (filesz == cur) break;
}


TCP의 흐름 제어/Sliding Window

2. Sliding Window

방금 알아본 바와 같이 Stop and Wait를 사용하여 흐름 제어를 하게 되면 비효율적인 부분이 있기 때문에, 오늘날의 TCP는 특별한 경우가 아닌 이상 대부분 슬라이딩 윈도우(Sliding Window) 방식을 사용한다.
슬라이딩 윈도우는 수신 측이 한 번에 처리할 수 있는 데이터를 정해놓고 그때그때 수신 측의 데이터 처리 상황을 송신 측에 알려줘서 데이터의 흐름을 제어하는 방식이다.
Stop and Wait과 여러 가지 차이점이 있겠지만, 
사실 가장 큰 차이점은 송신 측이 수신 측이 처리할 수 있는 데이터의 양을 알고 있다는 점이다. 
이 정보를 알고 있기 때문에 굳이 수신 측이 처리 가능이라는 대답을 일일히 해주지 않아도 데이터를 보내기 전에 이게 처리될 지 어떨지 어느 정도 예측이 가능하다는 말이다.

 

 

dirent.h
0.01MB
windows_file_recv.c
0.01MB
windows_file_send.c
0.00MB
windows_recv_basic.c
0.00MB
windows_send_basic.c
0.00MB
windows_send_byte.c
0.00MB

변형적인 file recv/send(windows)

1. 파일이름을 보낸다.(서버에서 파일중복검사를 하지 않고, YYYYMMDDHHMISS_FILENAME으로 처리)

2. 파일내용을 읽어서 보낸다.

windows_send_byte.c
0.00MB
windows_recv_byte.cs
0.00MB

 

 

문의)xterm92@naver.com

일반적인 file send/recv(windows src)

1. 클라이언트에서 파일사이즈를 보내고

2. 클라이언트에서 파일이름을 보내고

3. 파일을 읽어서 전송

 

 

 

dirent.h
0.01MB
windows_file_recv.c
0.01MB
windows_file_send.c
0.00MB

c# 으로 작성되어진 delemeter(0xff)로 구분되어진 데이타 수신서버

windows_send_basic.c
0.00MB
other_rcv.cs
0.00MB
windows_recv_basic.c
0.00MB

애플리케이션 성능 모니터링이란?

 

애플리케이션 성능 모니터링인 APM은 조직이 애플리케이션 및 코드의 성능 문제를 신속하게 식별하고 해결하기 위한 프로세스입니다.

APM 솔루션은 웹사이트, 소프트웨어 애플리케이션 및 서비스에서 원격 측정 데이터를 수집, 모니터링 및 분석합니다. 팀은 애플리케이션 전반에 걸쳐 엔드 투 엔드 가시성을 확보하여 애플리케이션 및 서비스 종속성을 파악하고 오류나 속도 저하를 해결할 수 있습니다. 또한 APM 솔루션은 추세를 표면화하기 위해 과거 데이터를 저장하고 활용하며, 비즈니스 KPI뿐만 아니라 대기 시간 및 처리량과 같은 주요 성능 지표에 대한 이상값을 탐지합니다.

애플리케이션 성능 모니터링의 역할은 무엇인가요?

애플리케이션 성능 모니터링은 애플리케이션의 성능에 대한 지속적이고 상세한 인사이트를 제공합니다. 팀은 이러한 인사이트를 활용하여 고객의 불만 사항을 기다리는 대신 보다 사전 예방적으로 대처할 수 있습니다. APM에는 여러 가지 용도가 있습니다. 예를 들어, 팀은 사용자 경험의 저하에 대한 경보 기능을 설정하고, 최신 릴리즈의 영향을 측정하고, 개선해야 할 부분에 대해 정보에 입각한 결정을 내릴 수 있습니다. 또한 근본 원인 분석을 지원하고 평균 탐지 시간(MTTD) 및 평균 해결 시간(MTTR)을 낮추는 데에도 사용할 수 있습니다.

APM이 중요한 이유는 무엇인가요?

애플리케이션은 현대 조직에서 필수불가결한 요소입니다. 애플리케이션은 사람들이 매일 사용하는 제품, 서비스 및 도구의 관문이며, 또한 점점 더 복잡해지고 있습니다. 클라우드 네이티브 기술  마이크로서비스와 같은 분산 애플리케이션이 증가함에 따라, 팀은 스트리밍되는 원격 측정 데이터의 양을 따라잡을 수 없습니다. 탁월한 사용자 경험을 제공하기 위해 모든 것을 모니터링하는 방법이 필요합니다.

APM은 애플리케이션이 예상대로 작동하도록 보장합니다. 고객의 신뢰를 유지하기 위해, APM 도구는 팀에게 잠재적인 문제에 대한 경보를 보내 문제를 신속하게 해결할 수 있습니다.

APM의 역사

1990년대에 만들어진 이래로, APM은 IT 팀에게 이전에는 전혀 가시성이 없던 애플리케이션에 대한 가시성을 제공해 왔습니다. 수년에 걸쳐, 여러 회사가 분산 추적을 실험했지만 2010년대가 되어서야 보다 강력한 APM 솔루션이 출시되었습니다. 이러한 플랫폼 솔루션은 보다 높은 수준의 추적과 엔드 투 엔드 모니터링 기능을 제공합니다.

APM과 Observability 비교

표면적으로는 Observability와 APM이 유사합니다. 둘 다 텔레메트리를 사용하여 데이터를 수집하고 성능에 대한 인사이트를 제공합니다. APM은 트랜잭션 추적과 모니터링 등 보다 애플리케이션 중심적인 반면, Observability는 애플리케이션 및 인프라 성능 양쪽 모두에 적용됩니다. Observability를 통해 시스템에 대한 이해도를 높이기 위해 기술 세부 정보를 심층적으로 파악할 수 있습니다. Observability는 로그, 메트릭 및 추적 간의 상관 관계를 통해 팀이 성능 문제의 컨텍스트와 근본 원인을 파악할 수 있도록 지원합니다.

애플리케이션 성능 모니터링은 어떻게 작동하나요?

APM은 일련의 도구와 방법론을 사용하여 소프트웨어 애플리케이션의 성능을 모니터링하고 관리합니다. APM 도구에는 일반적으로 응답 시간, 처리량 및 오류율과 같은 주요 메트릭의 모니터링이 포함되어 성능 병목 현상 및 문제를 식별하고 진단합니다.

APM 도구는 또한 개발자들이 코드의 문제를 이해하고 해결하는 데 도움이 되는 상세한 추적 및 디버깅 정보를 제공할 수 있습니다. 여기에는 이해관계자에게 애플리케이션의 성능을 지속적으로 알리기 위한 경보 및 보고 기능이 포함되는 경우가 많습니다.

APM 에이전트

에이전트는 일반적으로 애플리케이션에서 계측되는 소프트웨어입니다. 에이전트는 추적 및 원격 측정 데이터를 모니터링하고 APM 서버 및/또는 기타 모니터링 도구로 전송합니다. 에이전트를 사용하여 광범위한 시스템 및 애플리케이션을 모니터링할 수 있으며, 성능의 특정 측면에 대한 데이터를 수집하도록 에이전트를 구성할 수 있습니다.

APM 계측

계측은 성능 데이터를 수집하기 위해 애플리케이션에 모니터링 코드를 추가하는 프로세스입니다. 응답 시간, 오류율, 리소스 활용률, 로그 및 기타 애플리케이션 상태와 성능의 주요 지표에 대한 메트릭을 수집하는 데 사용할 수 있습니다.

계측은 공급업체별 APM SDK(소프트웨어 개발 키트)를 사용하거나 또는 스팬을 사용해 추적이 시작되고 중지되는 OpenTelemetry와 같은 개방형 표준을 사용하여 수동으로 수행할 수 있습니다.

또는 코드를 자동으로 계측하는 에이전트를 사용하여 수행할 수도 있습니다. 에이전트를 설치한 후, 팀은 분석을 위해 애플리케이션 또는 트랜잭션의 특정 부분을 계측한 다음 데이터를 엔드포인트(일반적으로 APM 플랫폼)로 전송할 수 있습니다. 계측은 보통 도구의 UI에서 또는 API를 통해 설정됩니다. 구성의 예로는 환경 이름, 샘플링 속도 및 기타 메트릭이 있습니다.

APM 분석 및 경보

성능 데이터가 수집되면 분석을 할 수 있습니다. 도구를 선택할 때는 사용자의 경험을 쉽게 추적하고 오류 및 문제를 한눈에 파악할 수 있는 대시보드와 보기가 포함되어 있어야 합니다. 대부분의 팀은 보고된 문제에 대한 조사를 시작한 다음, 근본 원인을 파악하기 위해 노력합니다. APM에 대한 플랫폼 접근 방식을 갖게 되면, 이 단계에서 도구 전환을 방지할 수 있습니다. 향후 문제를 방지하기 위해 경보를 설정할 수도 있습니다.

APM은 무엇을 측정하나요?

APM 도구는 다음을 측정할 수 있습니다.

  • 서버 상태: 서버 CPU 사용량, 메모리 요구량 및 읽기/쓰기 속도 모니터링
  • 오류율: 성능 저하 추적 및 문제 식별
  • 응답 시간: 애플리케이션 성능에 영향을 미치고 있는지 여부 확인
  • 인스턴스: 효율적으로 확장하고 전체 비용을 관리하기 위해 실행 중인 서버 또는 앱 인스턴스 수 파악. 이 메트릭은 클라우드 기반 애플리케이션에 매우 중요합니다.
  • 요청 속도: 사용자 트래픽을 평가하여 급증이 발생하거나 사용자가 비활성화되는 이유 파악
  • 가용성: 애플리케이션의 가동 시간 추적

 

APM의 어려움은 무엇인가요?

APM 도구에는 어려움이 따르게 마련입니다. 팀들은 실시간으로 방대한 양의 데이터 스트리밍을 처리하는 중입니다. 복잡하고 분산된 애플리케이션, 특히 클라우드 네이티브 기술을 사용하는 애플리케이션은 APM 계측을 어렵게 만들 수 있습니다. 환경 전반에 걸쳐 문제가 있거나 복잡한 근본 원인 분석 사례가 있는 경우, 많은 도구가 어려움을 겪을 수 있습니다.

APM 솔루션은 엔드 투 엔드 트랜잭션, 애플리케이션 및 코드 레벨 성능을 모니터링하여 조직에 포괄적인 적용 범위를 제공해야 합니다. 단일 플랫폼을 사용하면 가장 포괄적인 적용 범위를 제공하고, 워크플로우를 단순화하고, 문제 해결 속도를 높일 수 있습니다. 비즈니스 목표를 달성하기 위해 여러 모니터링 방법을 조합하여 사용할 수 있는 적절한 APM 솔루션을 선택하는 것이 중요합니다.

 

APM의 이점은 무엇인가요?

애플리케이션이 작동을 멈추면, 사용자에게 부정적인 경험을 주기 전에 미리 아는 것이 좋습니다. APM을 통해 팀은 문제를 신속하게 파악하고 해결할 수 있으며, 향후에도 문제를 방지할 수 있습니다. 포괄적인 APM 도구를 통해, 팀은 다음과 같은 이점을 얻을 수 있습니다.

  • 안정성 및 가동 시간 향상
  • 인시던트 감소
  • 문제를 보다 신속하게 해결
  • 고품질 소프트웨어 출시
  • 인프라 개선 사항 파악
  • 생산성 향상
  • 더 나은 사용자 경험 만들기
  • 매출 증대

 

APM 도구의 주요 기능

적절한 APM 도구를 선택할 때 어떤 점을 고려해야 하나요? 엔드 투 엔드 트랜잭션, 애플리케이션 및 코드 레벨 성능을 모니터링할 수 있는 다양한 APM 솔루션이 있지만, 현재와 미래의 기술적 필요에 맞는 솔루션을 선택하는 것이 중요합니다.

기술적 역량

조직에 대한 체크리스트를 작성합니다. 그런 다음, 필요에 따라 도구 기능을 비교할 수 있습니다. APM 기술적 역량의 예를 몇 가지 소개하면 다음과 같습니다.

  • 웹사이트 및/또는 애플리케이션 성능 추적
  • 애플리케이션 및 서비스 종속성 매핑 및 관리
  • 엔드 투 엔드 가시성을 위해 분산 추적 수집
  • 실시간 사용자 모니터링(클라이언트 및 서버) 제공
  • 앱 성능을 비즈니스 목표에 연결
  • 머신 러닝 및 AI 기반 분석 활용
  • 다양한 데이터 유형, 데이터 소스 및 언어 지원

 

 

엔드 투 엔드 가시성

APM 데이터는 애플리케이션에서 실제로 어떤 일이 일어나고 있는지를 조직에 알릴 수 있는 기능을 가지고 있습니다. 그러나 모든 것을 잘 모니터링할 수 있어야 어떻게 작동하고 있는지에 대한 명확한 비전을 얻을 수 있습니다.

개별 추적은 이 스토리의 일부만 보여주기 때문에, APM 도구는 한 단계 더 나아가 트랜잭션을 전체 과정에서 모니터링해야 합니다. 그런 다음, 여러 추적을 함께 연결하여 개괄적인 전체 보기에서 코드 레벨 문제로 전환할 수 있습니다.

엔드 투 엔드 가시성도 AIOps의 중요한 요소입니다.

통합

서드파티 서비스 및 애플리케이션과의 통합을 통해 APM 도구는 조직의 보다 규모가 큰 에코시스템에 원활하게 꼭 들어맞을 수 있습니다. 인증에서 CI/CD 프레임워크에 이르기까지, 이러한 통합을 사전에 조사하는 것이 중요합니다.

사용 용이성

조직 내에는 APM 기능에 액세스해야 하는 다양한 사용자가 있습니다. 직관적인 UI를 통해 각 사용자의 필요에 맞추세요. 또한 APM 솔루션의 배포, 관리 및 확장이 얼마나 쉬운지 확인해 보세요.

배포 옵션

운영 및 관리 비용을 절감하려는 경우 ,클라우드 기반 SaaS 옵션을 고려해 볼 수 있습니다. 그러나 고려해야 할 다른 배포 옵션이 있습니다. 일부 APM 도구는 멀티 클라우드 또는 하이브리드 전략을 지원할 수 있지만, 다른 도구는 선호하는 클라우드 서비스 제공자에 따라 제한이 있을 수 있습니다.

개방형 표준/개방형 데이터 지원

Observability 공간은 끊임없이 진화하고 있습니다. 새로운 도구와 표준이 시장에 진입함에 따라, 적응할 수 있는 유연한 플랫폼이 필요합니다. 또한 OpenTelemetry와 같은 개방형 표준 및 기술을 사용하면 도구 집합의 미래를 보장하는 데 도움이 될 수 있습니다.

 

참조)
APM - 애플리케이션 성능 모니터링이란 무엇인가요? | 포괄적인 APM 안내서 | Elastic

 

APM - 애플리케이션 성능 모니터링이란 무엇인가요? | 포괄적인 APM 안내서

APM(애플리케이션 성능 모니터링)은 조직이 사용자 트랜잭션을 이해하고, 문제를 식별하며, 애플리케이션과 코드의 성능 문제를 해결하는 프로세스입니다. 애플리케이션 성능 모니터링에 대해

www.elastic.co

 

클라이언트에서 555사이즈 packet을 400번 보내면 서버에서 받는모습은(?)

1. 클라이언트에서 555사이즈 packet을 400번 보내면 555 * 400 = 222,000이다.

2. 파일에서의 사이즈는 229,200이다.("\r\n" + 기타정보를 추가로 입력했기때문에 사이즈가 늘어났다.)
-rw-r--r-- 1 B210145_BK 197121    229200 Apr 22 08:32 packefile_2024_04_22_08_32_24.txt
-rw-r--r-- 1 B210145_BK 197121    229200 Apr 22 08:34 packefile_2024_04_22_08_34_02.txt
-rw-r--r-- 1 B210145_BK 197121    229200 Apr 22 08:35 packefile_2024_04_22_08_34_58.txt

3. 클라이언트에서 555를 보낸다고해서, 서버에서 555을 받지는 않는다.
장비 네크워크 사정, 서버의 처리속도, 등등을 따져서 서버에서 받는 수신 packet 의 사이즈는 틀려진다.

4. 마지막 서버에서 모든 수신된 packet의 길이를 더하면 클라이언트에서 보낸 사이즈와 같다.

유실이 없다.(tcp/ip)

5. 위의 화면을 보면, 클라이언트에서 보내는 모습과 서버에서 받는모습이 나타나있다.
자세히 보면, 어떻게 클라이언트와 서버가 데이타를 주고받는지 알수 있다.

궁금한점은 xterm92@naver.com으로,ㅡㅡ,ㅡㅡㅡㅡ

 

+ Recent posts