콘솔프로그램을 작성시에 쓰레드를 발생시키고 종료를 막기위해서 반복문을 사용하는것 외에는
방법이 없는것 같았지만, 아래와 같은 방법을 쓰면 될듯함/

 

using System;
using System.Threading;

class Program
{
    // ManualResetEvent 객체 생성
    private static ManualResetEvent manualResetEvent = new ManualResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main 스레드 시작");

        // 새로운 스레드 시작
        Thread thread = new Thread(WorkerThread);
        thread.Start();

        // ManualResetEvent를 통해 메인 스레드를 대기시킴
        manualResetEvent.WaitOne();

        Console.WriteLine("Main 스레드 종료");
    }

    static void WorkerThread()
    {
        Console.WriteLine("Worker 스레드 시작");

        // 일부 작업을 수행
        Thread.Sleep(3000); // 예: 3초 동안 작업을 수행한다고 가정

        Console.WriteLine("Worker 스레드 종료");

        // 작업이 완료되면 ManualResetEvent를 설정하여 Main 스레드를 깨움
        manualResetEvent.Set();
    }
}

정보분배수신/SQLite저장/REDIS전송/REDIS BLPOP/WPF/

1. KRX정보분배 TCP 데이타 수신
2. SQLite DataBase 저장
3. JSON포맷으로 변환
4. REDIS전송
5. REDIS BLPOP Designed by WPF(기존 Prompt) - 해당부분 아래 이미지로 제공

5.1 <string,stgring> JSON 타입
5.2 <string,List>  JSON 타입으로 나누어서 표시해야 합니다.

1. KRX

2. MDIRedisTicker Server
2.1 - Tcp Recv & Parse
2.2 - SQLite Database
2.3 - Push TO Redis Server

3. HomeTradeCli.exe
3.1 - Pop From Redis Server


KRX)
[2024-08-01 19:18:53.316][00099][00079][IA000K2S09PKRD020020354090034000970.33+000000.55000000000202000000035314    ]
HTS)
[Title+Time]:ExturePlusTotalKseIndex[2024-08-01 19:18:53.326]
[Redis++Key];1127001637919216845106
[POP---Data];{"data_tp_val":"IA","info_tp_val":"000","if_idx_id":"K2S09P","std_cd":"KRD020020354","idx_calc_tm":"090034","if_calc_idx":"000970.33","cmpprevdd_idx_sgn":"+","cmpprevdd_calc_idx":"000000.55","idx_acc_trdvol":"000000000202","idx_acc_trdval":"000000035314","filr_val4":"    ","ms_msg_end_keywrd":"NULL"}

KRX -> HTS까지 걸린시간은( [2024-08-01 19:18:53.316] - [2024-08-01 19:18:53.326] ) 의 시간 차이를 보이고 있다.

제목) 정보분배/SQLite/Cache/Redis/WebHttp/Manual Program

1. 정보분배 TCP데이타 제공처(KRX)
증권정보데이타(Securities Information Data)는 주식, 채권, 파생상품 등 다양한 금융 상품에 대한 정보를 제공하는 데이터입니다. 
이 데이터는 투자자, 금융 기관, 애널리스트 및 연구원들이 시장 동향을 파악하고 투자 결정을 내리는 데 중요한 역할을 합니다.
주식 데이터:
가격 정보: 시가, 종가, 고가, 저가, 거래량, 거래대금 등.
주식 지표: PER(주가수익비율), PBR(주가순자산비율), EPS(주당순이익) 등.
파생상품 데이터:
선물/옵션 정보: 기초 자산, 만기일, 행사가격, 거래량 등.
파생상품 지표: 변동성, 델타, 감마, 세타 등 그릭스(Greeks) 값.
거래소 정보:
지수 정보: 종합주가지수, 섹터별 지수, 글로벌 지수 등.
시장 통계: 거래소 전체의 거래량, 거래대금, 상장 종목 수 등.
데이터 제공 방법
실시간 데이터: 거래소와 데이터 제공업체가 실시간으로 업데이트되는 데이터를 제공합니다.
주요 제공 업체
한국거래소: 국내 주식, 채권, 파생상품의 거래 데이터를 제공합니다.
증권정보데이타는 금융 시장 참여자들이 시장을 이해하고 효과적으로 대응할 수 있도록 돕는 중요한 도구입니다. 

프로그램 테스트를 위한 과거데이타 전송)

2. Manual Program(직접만든프로그램) - mdimmmcache.exe

2.1 정보분배 TCP데이타 수신(21111 포트)
2.2 정보분배 TCP데이타를 SQLite DB에 저장(파일저장)
2.3 정보분배 TCP데이타를 Web Browser의 Request에 Response 응답(JSON데이타 포맷) - 8080포트
2.4 정보분배 TCP데이타를 Manual Program - sendrcvredis.exe 의 Request에 Response 응답(JSON데이타 포맷)
- 6379포트

비고) SendMessage를 이용한 Debugging(Windows에서 SendMessage를 이용해서 로그를 보는것이 편하다.)


비고) Web Browser에서 Request시에, JSON포맷으로 Response 받는예.


3. SQLite DataBase
SQLite는 가벼운 디스크 기반 데이터베이스 관리 시스템(DBMS)입니다. 
여기서 "가벼운"은 소프트웨어의 크기와 자원 소비가 적다는 것을 의미합니다. 
SQLite는 서버 기반 DBMS와 달리 클라이언트-서버 구조가 아닌 내장형 데이터베이스로, 어플리케이션에 직접 통합됩니다.

주요 특징
독립형:

SQLite는 단일 파일로 모든 데이터베이스를 저장합니다. 이는 배포와 백업을 간단하게 만듭니다.
제로 설정:
설치나 초기 설정이 필요 없습니다. SQLite 라이브러리 파일을 어플리케이션에 포함시키면 바로 사용할 수 있습니다.
서버리스:
별도의 서버 프로세스가 필요 없습니다. 어플리케이션이 직접 SQLite 데이터베이스 파일을 읽고 쓸 수 있습니다.
크로스 플랫폼:
다양한 운영체제에서 동작하며, 동일한 데이터베이스 파일이 여러 플랫폼에서 호환됩니다.
높은 신뢰성:
SQLite는 트랜잭션을 지원하며, ACID(Atomicity, Consistency, Isolation, Durability) 속성을 보장합니다.
표준 SQL 지원:
대부분의 SQL-92 표준을 지원합니다. 하지만 몇 가지 고급 기능은 지원하지 않을 수 있습니다.
사용 사례
임베디드 시스템:
모바일 장치, IoT 기기, 가전제품 등에서 많이 사용됩니다.
테스트 및 프로토타이핑:
서버 기반 DBMS의 복잡성을 피하기 위해 초기 개발 단계에서 사용됩니다.
데스크탑 응용 프로그램:
여러 데스크탑 애플리케이션에서 데이터 저장을 위해 사용됩니다.
웹 브라우저:
브라우저 내부에서 사용자의 데이터를 저장하기 위해 사용됩니다. 예: Google Chrome, Firefox의 내부 데이터 저장.
장단점
장점:
매우 가볍고 빠릅니다.
설정이 간단하고 사용이 편리합니다.
소스 코드가 공개되어 있어 수정 및 커스터마이징이 가능합니다.
파일 기반이므로 이동성과 백업이 용이합니다.
단점:
동시성이 필요한 대규모 애플리케이션에서는 성능이 떨어질 수 있습니다.
고급 기능(예: 저장 프로시저, 사용자 정의 함수 등)이 부족할 수 있습니다.
대용량 데이터를 처리하는 데는 적합하지 않을 수 있습니다.



4. REDIS
Redis는 오픈 소스 인메모리 데이터 구조 저장소로, 주로 고성능의 실시간 애플리케이션을 위해 사용됩니다. 
Redis는 "Remote Dictionary Server"의 약자로, 다양한 데이터 구조를 지원하며, 높은 속도와 확장성을 제공하는 것이 특징입니다.

주요 특징
인메모리 데이터베이스:
Redis는 데이터를 메모리에 저장하므로 매우 빠른 읽기 및 쓰기 속도를 제공합니다. 디스크에도 비동기적으로 데이터를 저장할 수 있어 내구성을 보장합니다.
다양한 데이터 구조 지원:
문자열, 리스트, 셋(set), 해시(hash), 정렬된 셋(sorted set), 비트맵(bitmap), 하이퍼로그로그(hyperloglog), 지오스페이셜 인덱스(geospatial index) 등의 다양한 데이터 구조를 지원합니다.
퍼시스턴스:
데이터를 디스크에 저장하여 메모리에서 데이터가 손실되는 것을 방지할 수 있습니다. RDB(Snapshotting)와 AOF(Append Only File) 두 가지 방식으로 퍼시스턴스를 제공합니다.
사용 사례
캐싱:빠른 데이터 액세스를 위해 자주 사용되는 데이터를 캐시합니다.
세션 저장소:웹 애플리케이션의 사용자 세션 데이터를 저장합니다.
실시간 분석:실시간 로그 처리 및 데이터 분석에 사용됩니다.
메시지 큐:Pub/Sub 메시징 시스템을 통해 메시지 큐로 사용할 수 있습니다.
장점:
매우 빠른 속도와 낮은 지연 시간.
다양한 데이터 구조 지원.
높은 가용성과 확장성.
단순하고 직관적인 API.
단점:
메모리에 데이터를 저장하므로 메모리 용량에 제한이 있음.



6. Manual Program(직접만든프로그램) - sendrcvredis.exe

REDIS PUSH/POP을 테스트할수 있는 프로그램

윈도우에서 특정 프로그램의 네트워크 상태를 확인하기 위해 사용할 수 있는 몇 가지 명령어가 있습니다. 
대표적으로 netstat 명령어가 많이 사용되며, tasklist와 findstr을 조합하여 특정 프로그램에 대한 정보를 확인할 수 있습니다.

netstat:

네트워크 연결 상태를 확인할 수 있는 기본 명령어입니다.
특정 프로그램의 네트워크 연결을 확인하려면 -b 옵션을 사용하여 실행 중인 각 연결의 실행 파일을 표시할 수 있습니다. 이 명령은 관리자 권한으로 실행해야 합니다.
netstat -anob

tasklist:

현재 실행 중인 프로세스 목록을 확인할 수 있습니다.
특정 프로그램의 PID(Process ID)를 찾을 때 유용합니다.

tasklist | findstr [프로그램 이름]

netstat과 findstr 조합:

특정 프로그램의 네트워크 연결 상태를 PID를 통해 필터링할 수 있습니다.
먼저 프로그램의 PID를 찾습니다:

tasklist | findstr [프로그램 이름]

그런 다음 해당 PID로 네트워크 상태를 필터링합니다:

netstat -ano | findstr [PID]
예를 들어, 특정 프로그램(예: redis-server.exe)의 네트워크 상태를 확인하려면 다음과 같은 단계를 따릅니다:

redis-server.exe의 PID를 찾습니다:

tasklist | findstr redis-server.exe
찾은 PID를 사용하여 네트워크 상태를 확인합니다(예를 들어, PID가 1234라면):

netstat -ano | findstr 1234
이 명령어들을 통해 특정 프로그램의 네트워크 연결 상태를 쉽게 확인할 수 있습니다.

ex)
예로써 개발되어진 프로그램은 다음의 네트웍 통신을 할수 있다.
mdiwebrowser.exe
1. 21111 포트로 정보분배 데이타를 수신한다.
2. 6379 포트로 REDIS서버에 송수신을 한다.
3. 8080 포트로 HTTP Request & Response를 한다.

B210145_BK@DESKTOP-QNNUCER MINGW64 ~
$ tasklist | findstr mdiweb
mdiwebrowser.exe             42720 Console                    3     52,844 K

B210145_BK@DESKTOP-QNNUCER MINGW64 ~
$ netstat -ano | findstr 42720
  TCP    127.0.0.1:21111        0.0.0.0:0              LISTENING       42720
  TCP    127.0.0.1:64279        127.0.0.1:6379         ESTABLISHED     42720
  TCP    127.0.0.1:64285        127.0.0.1:6379         ESTABLISHED     42720

B210145_BK@DESKTOP-QNNUCER MINGW64 ~
$


8080포트가 나오지 않는 이유는?

command)
>msbuild mdiwebrowser.sln /p:Configuration=Release

 

만약 Visual Studio를 사용하지 않고 명령줄에서 빌드하려면, MSBuild를 사용할 수 있습니다. MSBuild는 Visual Studio와 함께 설치되며, 명령줄에서 프로젝트를 빌드할 수 있는 도구입니다.

MSBuild 명령 실행:

  • 다음 명령어를 입력하여 솔루션을 빌드합니다: 
  • msbuild mdiwebrowser.sln
  • 기본적으로 MSBuild는 Release 또는 Debug 모드로 빌드할 수 있으며, 모드를 지정하려면 다음과 같이 명령어를 수정합니다:
    msbuild mdiwebrowser.sln /p:Configuration=Release
    또는
    msbuild mdiwebrowser.sln /p:Configuration=Debug

이 방법으로 프로젝트를 빌드하면, 결과물은 솔루션의 설정에 따라 bin\Release 또는 bin\Debug 폴더에 생성됩니다.

REIDS서버
REDIS클라이언트 - 접속상태

 

  TCP    0.0.0.0:6379           0.0.0.0:0              LISTENING
  TCP    127.0.0.1:6379         127.0.0.1:64279        ESTABLISHED
  TCP    127.0.0.1:6379         127.0.0.1:64285        ESTABLISHED
  TCP    127.0.0.1:64279        127.0.0.1:6379         ESTABLISHED
  TCP    127.0.0.1:64285        127.0.0.1:6379         ESTABLISHED
  TCP    [::]:6379              [::]:0                 LISTENING

 

> netstat -an | grep 6379 명령의 출력 결과를 해석하면 다음과 같습니다:

이 TCP 연결 정보를 해석하면 다음과 같습니다:

  1. 0.0.0.0:6379가 0.0.0.0:0에 대해 LISTENING 상태에 있음:
    • 이 행은 서버가 모든 네트워크 인터페이스에서 6379 포트를 듣고 있음을 나타냅니다.
    • 0.0.0.0는 모든 IPv4 주소를 의미합니다.
  2. 127.0.0.1:6379가 127.0.0.1:64279에 대해 ESTABLISHED 상태에 있음:
    • 이 행은 로컬 호스트(127.0.0.1)에서 6379 포트와 로컬 호스트에서 64279 포트 사이에 확립된 연결이 있음을 나타냅니다.
    • 즉, 이 연결은 같은 컴퓨터 내에서 이루어졌습니다.
  3. 127.0.0.1:6379가 127.0.0.1:64285에 대해 ESTABLISHED 상태에 있음:
    • 이 행도 유사하게 로컬 호스트에서 6379 포트와 로컬 호스트에서 64285 포트 사이에 확립된 연결이 있음을 나타냅니다.
  4. 127.0.0.1:64279가 127.0.0.1:6379에 대해 ESTABLISHED 상태에 있음:
    • 이 행은 위의 두 번째 행과 쌍을 이룹니다. 64279 포트에서 6379 포트로의 연결이 확립됨을 나타냅니다.
  5. 127.0.0.1:64285가 127.0.0.1:6379에 대해 ESTABLISHED 상태에 있음:
    • 이 행은 위의 세 번째 행과 쌍을 이룹니다. 64285 포트에서 6379 포트로의 연결이 확립됨을 나타냅니다.
  6. [::]:6379가 [::]:0에 대해 LISTENING 상태에 있음:
    • 이 행은 서버가 모든 IPv6 인터페이스에서 6379 포트를 듣고 있음을 나타냅니다.
    • [::]는 모든 IPv6 주소를 의미합니다.

요약하면, 이 정보는 서버가 6379 포트를 통해 여러 연결을 처리하고 있으며, 이 포트는 IPv4 및 IPv6 주소 모두에서 LISTENING 상태에 있습니다. 로컬 호스트에서 몇몇 확립된 연결(ESTABLISHED)이 존재합니다. 6379 포트는 일반적으로 Redis 서버가 사용하는 포트입니다.

SetVisibleCore 메서드는 Windows Forms에서 컨트롤의 가시성을 설정할 때 사용되는 메서드입니다. 이를 재정의(override)하면 컨트롤이 표시되거나 숨겨질 때 실행되는 기본 동작을 사용자 정의할 수 있습니다.

기본 정의

SetVisibleCore는 System.Windows.Forms.Control 클래스에 다음과 같이 정의되어 있습니다:

protected override void SetVisibleCore(bool value)

여기서 value는 컨트롤을 보이게 할지(true) 숨기게 할지(false)를 나타내는 부울 값입니다.

기본 동작

기본적으로 SetVisibleCore 메서드는 Visible 속성을 설정하고, 컨트롤의 기본 가시성 변경 작업을 처리합니다. 예를 들어, 컨트롤이 처음 생성될 때 보이도록 설정하거나, 가시성을 변경할 때 적절한 이벤트를 발생시키는 등의 작업이 포함됩니다.

사용자 정의

파생 클래스에서 SetVisibleCore를 재정의하여 특정 조건에 따라 컨트롤의 가시성을 제어할 수 있습니다. 다음은 SetVisibleCore를 재정의하여 특정 조건에 따라 컨트롤을 보이게 또는 숨기게 하는 예제입니다:

public class MyCustomControl : Form
{
     bool allowshowdisplay = false;
#if(true)
    protected override void SetVisibleCore(bool value)
    {
        base.SetVisibleCore(allowshowdisplay ? value : allowshowdisplay);
    }
#endif
#if(false)
    protected override void SetVisibleCore(bool value)
    {
        // 특정 조건을 만족할 때만 컨트롤을 표시
        if (ShouldControlBeVisible())
        {
Console.WriteLine("Show");
            base.SetVisibleCore(value);
        }
        else
        {
Console.WriteLine("Hide");
            base.SetVisibleCore(false);
        }
    }
#endif
    private bool ShouldControlBeVisible()
    {
        // 사용자 정의 조건 로직
        //return DateTime.Now.Second % 2 == 0; // 예: 현재 초가 짝수일 때만 보이도록
        return false;
    }
}
public class Program
{
    public static void Main()
    {
        Application.Run(new MyCustomControl());
    }
}

$ find ./ -name "*.cs" | xargs grep "Data Source"

grep 명령어 실행 시 "No such file or directory" 메시지를 피하려면, 다음과 같은 방법을 사용할 수 있습니다.
grep 명령어 실행 시 "No such file or directory" 메시지를 피하려면, 다음과 같은 방법을 사용할 수 있습니다.

B210145_BK@DESKTOP-QNNUCER MINGW64 ~/Downloads/EXTURE_3_0_APM_BASIC
$ find ./ -name "*.cs" | xargs grep "Data Source"
./APM/APM/APMMain.cs:            APMSQLite.GetInstance.Conn = new SQLiteConnection("Data Source=:memory:;Version=3;");
./APM/APM/APMMainForm.cs:            APMSQLite.GetInstance.Conn = new SQLiteConnection("Data Source=:memory:;Version=3;");
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Basic: No such file or directory
grep: Bars/BasicColumn.xaml.cs: No such file or directory
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Basic: No such file or directory
grep: Bars/BasicRowExample.xaml.cs: No such file or directory
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Basic: No such file or directory
grep: Stacked: No such file or directory
grep: Bar/BasicStackedColumnExample.xaml.cs: No such file or directory
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Basic: No such file or directory
grep: Stacked: No such file or directory
grep: Bar/BasicStackedRowPercentageExample.xaml.cs: No such file or directory
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Chart: No such file or directory
grep: to: No such file or directory
grep: Image/ChartToImageSample.xaml.cs: No such file or directory
grep: ./APM/Screen/Live-Charts-master/Examples/UWP/CartesianChart/Customized: No such file or directory
grep: Series/CustomizedLineSeries.xaml.cs: No such file or directory

1. 오류 메시지 무시하기: grep 명령어의 표준 오류를 /dev/null로 리디렉션하여 오류 메시지를 무시할 수 있습니다.

find ./ -name "*.cs" | xargs grep "Data Source" 2>/dev/null

2. 존재하는 파일만 찾기: find 명령어로 실제 존재하는 파일만 대상으로 하여 grep을 실행하도록 합니다. -exec 옵션을 사용하면 find 명령어가 각각의 파일에 대해 grep을 실행하게 할 수 있습니다.

find ./ -name "*.cs" -exec grep "Data Source" {} +

 

정보분배수신/SQLite DB저장(file)/(동기식)HttpListener Interface/
정보분배수신/SQLite DB저장(file)/(동기식)HttpListener Interface/
정보분배수신/SQLite DB저장(file)/(동기식)HttpListener Interface/

비고)
키워드를 사용하지 않고 HTTP 서버를 구현하는 방법을 보여드리겠습니다. 
이 경우, HttpListener를 사용하여 비동기 방식이 아닌 동기 방식으로 요청을 처리합니다. 
동기 방식은 코드가 요청을 처리하는 동안 다른 작업을 수행할 수 없으므로 서버의 응답 속도가 느려질 수 있습니다.


NuGet으로 Package를 설치시에, 최신버젼으로 빌드하시면 됩니다.
./packages/Newtonsoft.Json.13.0.3/lib/net45/Newtonsoft.Json.dll
./packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net45/x64/SQLite.Interop.dll
./packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/lib/net45/System.Data.SQLite.dll

1. 전체도식을 그려본다

 


- HTTP 인터페이스를 위한 8080포트 Listen
xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/exture_3_0_ticker/mdiwebrowser

$ netstat -an | grep 8080
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING
  TCP    [::]:8080              [::]:0                 LISTENING
  TCP    [::1]:8080             [::1]:50463            CLOSE_WAIT
  TCP    [::1]:8080             [::1]:50493            ESTABLISHED
  TCP    [::1]:8080             [::1]:50496            ESTABLISHED
  TCP    [::1]:50463            [::1]:8080             FIN_WAIT_2
  TCP    [::1]:50493            [::1]:8080             ESTABLISHED
  TCP    [::1]:50496            [::1]:8080             ESTABLISHED

- 정보분배 TCP데이타를 받기위한 21111포트 Listen
xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/exture_3_0_ticker/mdiwebrowser
$ netstat -an | grep 2111
  TCP    127.0.0.1:21111        0.0.0.0:0              LISTENING


2. 거래소정보분배 TCP데이타 수신및 저장(SQLite)

3. SQLite Browser에서 나타내봅니다.(상용)

3. 거래소정보분배 TCP데이타 인터페이스(HTTP통신) - 동기식(한번에 하나의 resquest를 처리한다.)

3.1 - Text 표시
3.2 - Json 표시

(의견)증권정보데이타를 클라이언트에 주는게,받는게 효과적(?)

1. 클라이언트에서 데이타를 받는게 효과적일까(?) - 실시간적으로

1.1 서버입장에서는 REDIS서버에 클라이언트가 가져갈 데이타를 쌓아놓기만 하면 된다.
1.2 요즘은, 클라이언트에게 담당하는 부분을 늘리는게 일반적이다.

2. 클라이언트에게 데이타를 주는게 효과적일까(?)  - 실시간적으로

2.1 서버입장에서는 클라이언트에 실시간으로 데이타를 주는입장이다. 조금 복잡할것 같다.
2.2 서버에서 모두 처리하기에는 조금 부담스럽다.

 

Windows OS에서 버퍼 캐시는 메모리 관리의 중요한 부분으로, 디스크 I/O 성능을 최적화하는 데 핵심적인 역할을 합니다. 버퍼 캐시의 주요 역할은 다음과 같습니다:

  1. 디스크 I/O 성능 향상:
    • 자주 접근하는 데이터나 파일 시스템 메타데이터를 메모리에 캐싱하여 디스크 접근을 줄입니다. 이를 통해 디스크에서 직접 데이터를 읽는 시간을 절약할 수 있습니다.
  2. 읽기 성능 개선:
    • 한 번 읽은 데이터를 메모리에 저장하여 동일한 데이터에 대한 후속 읽기 작업이 더 빠르게 수행될 수 있도록 합니다.
  3. 쓰기 성능 최적화:
    • 쓰기 작업을 먼저 메모리에 저장한 후, 일정 주기나 조건이 만족될 때 디스크에 기록합니다. 이를 통해 디스크에 대한 빈번한 쓰기 작업을 줄이고, 시스템의 전반적인 성능을 향상시킵니다.
  4. 메모리 사용의 효율성:
    • 사용하지 않는 메모리를 캐시로 활용하여 시스템의 효율성을 높입니다. 사용 중인 메모리가 부족할 경우, 캐시된 데이터를 삭제하거나 축소하여 더 중요한 작업에 메모리를 할당할 수 있습니다.
  5. 데이터 일관성 유지:
    • 데이터를 디스크에 기록하기 전에 메모리에 캐싱하여 데이터의 일관성을 유지하고, 시스템 크래시나 전원 장애 시 데이터 손실을 방지하는 메커니즘을 제공합니다.

버퍼 캐시는 이러한 기능을 통해 전체적인 시스템 성능을 향상시키고, 사용자 경험을 개선하는 중요한 역할을 합니다.


  • PowerShell을 CMD에서 실행하는 방법: CMD를 열고 PowerShell 명령어를 실행하여 시스템의 버퍼 캐시를 확인할 수 있습니다.
  • PowerShell 명령어: 버퍼 캐시 및 메모리 상태를 확인하기 위해 Get-WmiObject를 사용할 수 있습니다.

 

 

Windows OS에서 버퍼 캐시 상태를 CMD(Command Prompt)에서 확인하는 명령어는 Get-Process 및 Get-WmiObject를 활용하여 PowerShell을 통해 확인할 수 있습니다. Windows CMD 자체에서는 이러한 정보를 직접적으로 제공하지 않기 때문에 PowerShell을 사용해야 합니다.



powershell "Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Memory"
PS C:\Users\B210145_BK> powershell "Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Memory"


__GENUS                              : 2
__CLASS                              : Win32_PerfFormattedData_PerfOS_Memory
__SUPERCLASS                         : Win32_PerfFormattedData
__DYNASTY                            : CIM_StatisticalInformation
__RELPATH                            : Win32_PerfFormattedData_PerfOS_Memory=@
__PROPERTY_COUNT                     : 45
__DERIVATION                         : {Win32_PerfFormattedData, Win32_Perf, CIM_StatisticalInformation}
__SERVER                             : DESKTOP-QNNUCER
__NAMESPACE                          : root\cimv2
__PATH                               : \\DESKTOP-QNNUCER\root\cimv2:Win32_PerfFormattedData_PerfOS_Memory=@
AvailableBytes                       : 2399301632
AvailableKBytes                      : 2343068
AvailableMBytes                      : 2288

CacheBytes                           : 186159104
CacheBytes                           : 186159104
CacheBytes                           : 186159104
CacheBytes                           : 186159104
CacheBytes                           : 186159104
CacheBytes                           : 186159104

CacheBytesPeak                       : 322740224
CacheFaultsPersec                    : 0
Caption                              :
CommitLimit                          : 15726735360
CommittedBytes                       : 7436763136
DemandZeroFaultsPersec               : 11
Description                          :
FreeAndZeroPageListBytes             : 3473408
FreeSystemPageTableEntries           : 12448459
Frequency_Object                     :
Frequency_PerfTime                   :
Frequency_Sys100NS                   :
LongTermAverageStandbyCacheLifetimes : 14400
ModifiedPageListBytes                : 52383744
Name                                 :
PageFaultsPersec                     : 15
PageReadsPersec                      : 0
PagesInputPersec                     : 0
PagesOutputPersec                    : 0
PagesPersec                          : 0
PageWritesPersec                     : 0
PercentCommittedBytesInUse           : 47
PoolNonpagedAllocs                   : 0
PoolNonpagedBytes                    : 425037824
PoolPagedAllocs                      : 0
PoolPagedBytes                       : 436318208
PoolPagedResidentBytes               : 391467008
StandbyCacheCoreBytes                : 162533376
StandbyCacheNormalPriorityBytes      : 1496104960
StandbyCacheReserveBytes             : 737189888
SystemCacheResidentBytes             : 186159104
SystemCodeResidentBytes              : 8192
SystemCodeTotalBytes                 : 8192
SystemDriverResidentBytes            : 7569408
SystemDriverTotalBytes               : 34660352
Timestamp_Object                     :
Timestamp_PerfTime                   :
Timestamp_Sys100NS                   :
TransitionFaultsPersec               : 3
TransitionPagesRePurposedPersec      : 0
WriteCopiesPersec                    : 0
PSComputerName                       : DESKTOP-QNNUCER

SQLite를 활용한 TCP정보분배 데이타 수신및 저장

> SQLite를 활용한 TCP정보분배 데이타 수신및 저장

 

> 위의 프로그램에서 생성되어진 데이타베이스 파일을 상용SQLite DB Browser에서 열기(서로 파일이 호환됨)

SQLite는 MySQL나 PostgreSQL와 같은 데이터베이스 관리 시스템이지만, 서버가 아니라 응용 프로그램에 넣어 사용하는 비교적 가벼운 데이터베이스이다. 
일반적인 RDBMS에 비해 대규모 작업에는 적합하지 않지만, 중소 규모라면 속도에 손색이 없다. 또 API는 단순히 라이브러리를 호출하는 것만 있으며, 데이터를 저장하는 데 하나의 파일만을 사용하는 것이 특징이다. 버전 3.3.8에서는 풀텍스트 검색 기능을 가진 FTS1 모듈이 지원된다. 컬럼을 삭제하거나 변경하는 것 등이 제한된다.
구글 안드로이드 운영 체제에 기본 탑재된 데이터베이스이기도 하다.

RDBMS( oracle, mssql, sysbase, mysql, mariadb 등)와 동일하게 ansi sql을 사용할 수 있다.
다른 RDBMS와의 가장 큰 차이점은 아래와 같다.
데이터베이스별로 파일1개로 구성된다.
로컬에 파일로 저장하므로 원격접속이 안된다. 
( 웹서버와 DB서버를 별도로 구성 X, 다른 대안은 찾아보면 있다. 다른아이피의 PC를 마운트 해서 사용한다던가..등)
접속아이디나 패스워드가 없다.
다중 접속이 많아질 경우 예기치 않은 문제가 발생할 수 있다.
구글 안드로이드 운영 체제에 기본 탑재되어 있어 앱을 만들어본 경험이 있다면, 누구나 한번쯤은 사용해보고 들어봤을 것이다.
윈도우PC에서도 설치하여 사용할 수 있으며, 간단한 웹페이지를 구현할때도 별도의 설치과정이 없이 실행파일만 있으면 바로 사용할 수 있다.


1. SQLite 다운로드
http://www.sqlite.org/download.html 에 접속하여 sqllite-tools-win32-3340000.zip 파일을 다운로드 받는다.

2. 압축해제 후 sqlite3.exe 실행
적당한 곳(ex. C:\SQLite)에 압축을 푼 다음 sqlite.exe파일을 실행한다.
간혹 아래와 같이 Windows의 PC 보호라고 알림 창이 뜰 경우 "추가 정보"를 클릭 후 나타나는 "실행" 버튼을 클릭하면 된다.

3. sqlite 명령프롬프트
실행하면 윈도우 명령 프롬프트가 실행되면서 sqlite 상태로 들어간다.

5. 데이터베이스 생성
실행했으니 데이터베이스를 하나 만들고 테이블도 하나 만들어서 값을 입력하고 결과를 조회해보자

데이터베이스를 만드는 법은 2가지가 있는데, 명령 프롬프트에서 sqlite3를 실행하면서 만드는 방법과 sqlite3 안에 들어가서 만드는 방법이 있다.
방법1. sqlite3 실행과 동시에 만들기

6. 생성된 데이터베이스에 테이블 만들기
일반적인 DDL 문법으로 TEST_TABLE 이라는 테이블을 만들고 .table 명령으로 테이블 목록을 조회

7. 생성된 테이블에 데이터 넣고 조회 해보기

8. GUI 툴을 사용하여 편하게 입력한다.
  sqlitebrowser.org/dl/


개인작업내용)
SQLite를 사용하여 C#에서 테이블을 생성하고 데이터를 입력 및 조회하는 예제를 아래에 제공하겠습니다. 이 예제에서는 System.Data.SQLite를 사용합니다.

먼저, NuGet 패키지 관리자를 통해 System.Data.SQLite 패키지를 설치해야 합니다.
먼저, NuGet 패키지 관리자를 통해 System.Data.SQLite 패키지를 설치해야 합니다.

BUILD & ALL
$ find ./ -name "*Interop*.dll"
./frm/WinFrmTicker/packages/Microsoft.Office.Interop.Excel.15.0.4795.1001/lib/net20/Microsoft.Office.Interop.Excel.dll
./frm/WinFrmTicker/packages/Microsoft.Office.Interop.Excel.15.0.4795.1001/lib/netstandard2.0/Microsoft.Office.Interop.Excel.dll
./frm/WinFrmTicker/packages/MSOffice.Interop.16.0.55555/lib/Microsoft.Office.Interop.Access.Dao.dll
./frm/WinFrmTicker/packages/MSOffice.Interop.16.0.55555/lib/Microsoft.Office.Interop.Access.dll
./frm/WinFrmTicker/packages/MSOffice.Interop.16.0.55555/lib/Microsoft.Office.Interop.Excel.dll
./frm/WinFrmTicker/packages/MSOffice.Interop.16.0.55555/lib/Microsoft.Office.Interop.Visio.WorkflowAuthoring.dll
./frm/WinFrmTicker/WinFrmTicker/bin/Debug/Microsoft.Office.Interop.Visio.WorkflowAuthoring.dll
./frm/WinFrmTicker/WinFrmTicker/bin/Release/Microsoft.Office.Interop.Visio.WorkflowAuthoring.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net20/x64/SQLite.Interop.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net20/x86/SQLite.Interop.dll

dotnet40에서, 64비트)
dotnet40에서, 64비트)

./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net40/x64/SQLite.Interop.dll

./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net40/x86/SQLite.Interop.dll

dotnet45에서 , 64비트)
dotnet45에서 , 64비트)

./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net45/x64/SQLite.Interop.dll



./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net45/x86/SQLite.Interop.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net451/x64/SQLite.Interop.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net451/x86/SQLite.Interop.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net46/x64/SQLite.Interop.dll
./mdifrm/packages/Stub.Systehttp://m.Data.SQLite.Core.NetFramework.1.0.118.0/build/net46/x86/SQLite.Interop.dll
./mdifrm/WINCalcMdi/bin/Release/x64/SQLite.Interop.dll
./mdifrm/WINCalcMdi/bin/Release/x86/SQLite.Interop.dll



1. SQLite 데이터베이스 및 테이블 생성

using System;
using Systehttp://m.Data.SQLite;

class Program
{
    static void Main()
    {
        string connectionString = "Data Source=sample.db;Version=3;";

        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER NOT NULL
                )";

            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                command.ExecuteNonQuery();
            }

            connection.Close();
        }

        Console.WriteLine("Table created successfully.");
    }
}

2. 데이터 입력

using System;
using Systehttp://m.Data.SQLite;

class Program
{
    static void Main()
    {
        string connectionString = "Data Source=sample.db;Version=3;";

        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string insertQuery = "INSERT INTO users (name, age) VALUES (@name, @age)";

            using (SQLiteCommand command = new SQLiteCommand(insertQuery, connection))
            {
                command.Parameters.AddWithValue("@name", "Alice");
                command.Parameters.AddWithValue("@age", 30);
                command.ExecuteNonQuery();
            }

            connection.Close();
        }

        Console.WriteLine("Data inserted successfully.");
    }
}

3. 데이터 조회

using System;
using Systehttp://m.Data.SQLite;

class Program
{
    static void Main()
    {
        string connectionString = "Data Source=sample.db;Version=3;";

        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string selectQuery = "SELECT * FROM users";

            using (SQLiteCommand command = new SQLiteCommand(selectQuery, connection))
            {
                using (SQLiteDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Console.WriteLine("ID: " + reader["id"]);
                        Console.WriteLine("Name: " + reader["name"]);
                        Console.WriteLine("Age: " + reader["age"]);
                        Console.WriteLine();
                    }
                }
            }

            connection.Close();
        }
    }
}

전체 코드 예제

using System;
using Systehttp://m.Data.SQLite;

class Program
{
    static void Main()
    {
        string connectionString = "Data Source=sample.db;Version=3;";

        // 테이블 생성
        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string createTableQuery = @"
                CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name TEXT NOT NULL,
                    age INTEGER NOT NULL
                )";

            using (SQLiteCommand command = new SQLiteCommand(createTableQuery, connection))
            {
                command.ExecuteNonQuery();
            }

            connection.Close();
        }

        Console.WriteLine("Table created successfully.");

        // 데이터 입력
        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string insertQuery = "INSERT INTO users (name, age) VALUES (@name, @age)";

            using (SQLiteCommand command = new SQLiteCommand(insertQuery, connection))
            {
                command.Parameters.AddWithValue("@name", "Alice");
                command.Parameters.AddWithValue("@age", 30);
                command.ExecuteNonQuery();
            }

            connection.Close();
        }

        Console.WriteLine("Data inserted successfully.");

        // 데이터 조회
        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            string selectQuery = "SELECT * FROM users";

            using (SQLiteCommand command = new SQLiteCommand(selectQuery, connection))
            {
                using (SQLiteDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Console.WriteLine("ID: " + reader["id"]);
                        Console.WriteLine("Name: " + reader["name"]);
                        Console.WriteLine("Age: " + reader["age"]);
                        Console.WriteLine();
                    }
                }
            }

            connection.Close();
        }
    }
}

이 코드는 SQLite 데이터베이스를 생성하고, 테이블을 생성한 후, 데이터를 입력하고 조회하는 예제입니다. SQLite 데이터베이스 파일(sample.db)이 실행 디렉토리에 생성됩니다.


(정보분배)TCP로 받은 증권데이타를 파싱해서 DataGridView에 표시해봅니다.



1. SDI 방식
2. MDI 방식

1. 데이타의 정합성체크(소수점등)에 활용될수 있다.
2. *.db 파일에 저장되므로, 메모리의 크기에 대한 걱정을 안해도 된다.(무한정 데이타룰 수신가능)


접속표준서(정보분배-UDP_TCP실시간)에 정의되어진 콤마가 있는항목을 따로 표시해 봅니다.
누적거래량은 콤마3으로 표시되어지므로, ".000" 부분을 잘라서 사용해야 합니다.
"."까지 포함되어졌으므로, 4자리를 잘라서 사용해야 할것 같습니다.(주의할점)

 

TCP로 받은 호가데이타를 파싱해서 DataGridView에 표시해봅니다.

통합본)

public class PublicNM
{

     public const int WM_KEYDOWN = 0x0100;

    // FindWindow를 정적 메서드로 선언합니다.
    public static IntPtr FindWindow(string lpClassName, string lpWindowName)
    {
        // 실제 FindWindow 구현은 생략
        return IntPtr.Zero; 
    }
}

사용예)

         // 정적 메서드에 접근할 때는 클래스 이름을 사용합니다.
         IntPtr hWnd = PublicNM.FindWindow("ClassName", "WindowName");

        protected override bool ProcessCmdKey(ref Message message, Keys keyData)
        {
            switch (message.Msg)
            {
                case PublicNM.WM_KEYDOWN:
                    break;
                default:
                    break;
            }
            return base.ProcessCmdKey(ref message, keyData);
        }

증권정보,ㅡㅡ,ㅡㅡ packet send/recv in windows os

exture_send_basic.c
0.00MB
dirent.h
0.01MB
exture_recv_basic.c
0.00MB

 

 

c#/windows.pre.foundation/원리금균등상환.금리비교시.대출상환포함
c#/windows.pre.foundation/원리금균등상환.금리비교시.대출상환포함

Install Win.Form)



FiancialNM.msi
2.05MB


Install Win.Pre.Foundation)

FiancialCalc.msi
1.38MB



0. 메모장에서 코딩후 빌드 & 런

1. Win Form과 Win Presentaion Foundation과의 비교화면)

 

 


2. 대출상환정보가 없을경우)

3. 대출상환정보가 있을경우)

 

4. 대출상환정보가 있을경우>데이타선택시에, 해당월 일별 데이타 리스트출력

( ChatGPT )c# List 와 배열의 차이점

C#에서 List와 배열(Array)의 주요 차이점은 다음과 같습니다:

  1. 크기 조절 가능 여부:
    • 배열(Array): 배열은 선언된 크기를 초과하거나 축소할 수 없습니다. 한 번 생성되면 크기가 고정됩니다.
    • List: List는 동적으로 크기가 조절될 수 있습니다. 요소를 추가하거나 제거할 때 List 내부에서 자동으로 크기가 조절됩니다.
  2. 메서드와 기능:
    • 배열(Array): 배열은 .NET Framework에서 제공하는 여러 메서드와 기능이 있지만, 크기 조절이나 요소 추가/삭제에 제한이 있습니다. 예를 들어, Array 클래스는 Length 속성을 통해 배열의 길이를 확인할 수 있습니다.
    • List: List는 배열보다 다양한 메서드와 기능을 제공합니다. 예를 들어, 요소 추가/삭제를 위한 Add, Remove, Insert 메서드 등이 있습니다. 또한 LINQ 쿼리와 함께 사용할 수 있는 다양한 확장 메서드를 사용할 수 있습니다.
  3. 선언 및 초기화:
    • 배열(Array): 배열은 고정된 크기를 선언하고 초기화해야 합니다. 예를 들어, int[] numbers = new int[5];와 같이 선언하고 초기화합니다.
    • List: List는 크기를 선언하지 않고 생성할 수 있으며, 초기 요소를 포함할 수도 있습니다. 예를 들어, List<int> numbers = new List<int>();로 선언하고 초기화합니다.
  4. 타입 안정성:
    • 배열(Array): 배열은 특정 데이터 형식으로 타입 안전성을 보장합니다. 즉, 선언된 데이터 형식 이외의 데이터를 저장할 수 없습니다.
    • List: List는 제네릭 형식으로 제공되며, 특정 데이터 형식에 대한 타입 안정성을 보장합니다.

이러한 차이점으로 인해 상황에 따라 배열이나 List 중 하나를 선택하여 사용할 수 있습니다. 배열은 크기가 고정된 정적 데이터에 적합하고, List는 동적인 데이터 구조에 적합합니다.

+ Recent posts