____real_fast_no_ajax_hexa.html
0.02MB

 

 

#AJAX를 사용할 경우에(was 서버를 경우하게 되면), 2인 이상의 네트웍크 헥사를 구성할수 있습니다.

#AJAX를 사용할 경우에(was 서버를 경우하게 되면), 2인 이상의 네트웍크 헥사를 구성할수 있습니다.

주식 매매 체결 순서 설명

주식 체결 순서 원칙에 따르면 다음과 같은 일도 일어 납니다. 보유하고 있던 주식을 10,000원에 매도 주문을 냈는데 10,500원에 매도 되는 일 말입니다.
자주 일어나는 일은 아니지만, 주식 매매 원칙에 따르면 충분히 일어날 수 있는 일입니다.
주식 체결 순서 원칙은 주식 거래가 정규 시장, 동시호가 시간, 시간외 거래 시간 이루어지냐에 따라 조금 차이가 나는데요, 기본이 되는 정규 시장의 원칙부터 알아보겠습니다.

주식 거래는 정규 시장에 주로 이루어 지지만 아래와 같이 정규 거래 시간 외에도 주식을 거래할 수 있는 시간이 있습니다.
    - 정규 시장: 오전 9시 ~ 오후 2시 50분
    - 동시호가 시간: 오전 8시 ~ 오전 9시, 오후 2시 50분 ~ 오후 3시
    - 시간외 매매: 오전 7시 30분 ~ 오전 8시 30분, 오후 3시 ~ 오후 3시 30분, 오후 3시 30분 ~ 오후 6시
정규 시장 전 동시호가 시간과 오전 시간외 매매 시간 일부가 겹치는 것으로 보이지만, 시간외 매매는 정규 시장 거래 창이 아니라 별도의 거래 창에서 이루어 지기 때문에 거래가 겹치는 것은 아닙니다.

정규 시장 주식 체결 순서

가격 우선 → 시간 우선 → 수량 우선 순의 체결 원칙에 따라 매매가 이루어 지는데요, 구체적인 예를 들어 어떻게 이 원칙에 따라 매매가 체결 되는 지는 잠시 후에 알아 보겠습니다.자
정규 시장은 오후 3시까지이지만 마지막 10분 즉 오후 2시 50분에서 3시까지는 동시호가 체결 원칙에 따라 거래가 이루어 집니다. 따라서 가격, 시간, 수량 순의 우선 순위 체결 원직은 오전 9시부터 오후 2시 50분까지의 시간 동안 지켜지는 것이라고 보면 됩니다.

가격 우선 체결 원칙

주식을 사거나 팔 때 시장가로 매매 하기도 하지만, 보통은 매도 호가나 매수 호가를 지정하여 거래를 합니다.
가격 우선 원칙은 매도 호가는 낮은 가격이 높은 가격에 우선하고 매수 호가는 높은 가격이 낮은 가격에 우선한다는 원칙입니다.
이 원칙에 따르게 되면 여러 사람이 매도 호가와 매수 호가를 지정하여 주식을 매매 할 때, 가장 낮은 매도 호가를 부른 사람과 가장 높은 매수 호가를 부를 사람의 거래가 성립되게 됩니다.
이렇게 첫 번째 거래가 성립되고 나면 두 번째로 우선 순위를 갖는 매도자와 매수자와의 거래가 성립되고 또 다음 우선 순위를 갖는 거래가 성립되는 식으로 순차적으로 매매 거래가 체결 됩니다.
말은 이런 식으로 하지만 전산 처리되어 순식간에 체결이 이루어지죠. 물론 매도 우선 순위를 갖는 사람과 매수 우선 순위를 갖는 사람이 있지만 가격 조건이 맞지 않아 거래가 이루어 지지 않는 경우도 있습니다.

아래 예를 통해 구체적으로 살펴 보겠습니다.

어떤 주식에 대해 다음과 같이 매도 호가를 부른 사람 두 명(A와 B), 매수 호가를 부른 사람 두 명(갑과 을)이 있다고 가정해 보겠습니다.

    - A는 100주를 1주당 8,000원에 매도 하려고 하고,
    - B는 50주를 1주당 9,000원에 매도 하고자 함.
    - 갑은 100주를 1주당 10,000원에 매수 하려고 하고,
    - 을은 10주를 1주당 7,000원에 매수 하려고 함.
    - 가격 우선 체결 순서에 따르면 매도자 중에서는 낮은 매도 가격을 낸 A가 우선 순위를 가지고 매수자 중에서는 높은 매수 가격을 제시한 갑이 우선 순위를 가집니다.

A와 갑의 가격 조건을 보니 팔려는 사람(A)보다 사려는 사람(갑)이 비싸게 가격을 제시 했네요. 갑은 1주당 10,000원을 주고 100주는 매입하게 됩니다. A는 1주당 8,000원에 팔려고 했지만 갑 덕분에 1주당 10,000원에 팔 수 있게 되었습니다.
이번에는 다음 우선 순위를 가지는 B와 을의 가격 조건을 검토해 보겠습니다. B는 1주당 9,000원에 팔려고 하지만 을은 7,000원에 매수 하려고 합니다. 두 사람이 직접 만난다면 가격 흥정을 해 볼 수 있겠지만, 정규 주식 시장에서의 거래는 둘이 직접 만나 가격 흥정을 하는 식으로 거래가 성립 되지는 않지요.
그래서 B와 을 사이에는 가격이 맞지 않아 거래가 성립되지 않습니다. 결국 위의 예에서는 A와 갑사이에서만 거래가 성립됩니다.
실제 주식 시장에서는 위의 예 보다 훨씬 더 많은 매도자와 매수자가 있습니다. 따라서 실제 주식 체결 순서는 위 예보다는 좀 더 복잡하지만, 기본 원칙은 위에서 설명한 예와 같습니다.
가격을 기준으로 우선 순위를 가지는 매도자와 매수자를 걸러 내고 둘 사이에 가격이 맞다면 주식 매매가 체결 되고, 그 다음 우선 순위를 가지는 매도자와 매수자 간의 가격 조건을 검토하여 거래 성립 여부를 본 후, 또 그 다음 우선 순위를 가지는 매도자와 매수자의 거래 성립을 판단 하는 식으로 주식 거래가 이루어 집니다.

시간 우선 체결 원칙

앞의 예에서는 A와 B, 갑과 을이 서로 다른 가격을 제시한 것으로 가정했는데요, 만약 매도자들이 서로 같은 가격 또 매수자들이 서로 같은 가격을 제시한다면 어떻게 될까요?
바로 다음과 같은 상황인데요,

    - A: 한주당 8,000원 100주 매도 주문,
    - B: 한주당 8,000원 50주 매도 주문,
    - 갑: 한주당 10,000원 100주 매수 주문
    - 을: 한주당 10,000원 10주 매수 주문

가격이 같기 때문에 가격 우선 원칙을 적용하여 우선 순위를 가지는 사람을 판별할 수 없습니다.
그래서 등장하는 것이 시간 우선 원칙입니다. 즉, A가 B보다 먼저 매도 주문을 냈다면 매도자 중에서는 A가 우선 순위를 가지고 을이 갑보다 먼저 매수 주문을 냈다면 매수자 중에서는 을이 우선 순위를 가지게 되죠.
따라서 먼저 A와 을 사이에 거래가 성립 됩니다. 가격은 을의 매수 주문 가격인 한주당 10,000원이 됩니다. 그런데 을은 10주만 매수 하려 하기 때문에 A의 주식은 일단 10주만 매도 됩니다.
매도자 중에서 A는 아직도 90주(100주-10주)만큼 우선 순위를 가지고 있습니다. 매수자 중에서는 이제 갑만 남았습니다. 갑은 한주당 10,000원으로 A로부터 90주를 매수할 수 있게 됩니다.
갑은 100주를 구입하려 했으니 아직 10주를 구입 못한 상태입니다. 매도자 중에서 A는 팔려는 주식을 모두 팔았으니 이제 B만 남았습니다. 갑은 B로부터 한주당 10,000원으로 10주를 매수 하게 됩니다.

수량 우선 체결 원칙

앞에서 가격 우선 원칙을 살펴 보았고, 가격이 같다면 시간 우선 주식 체결 순서에 따라 거래가 성립 되는 것을 알아 보았습니다.
그런데, 가격도 같고 주문을 낸 시간도 같다면 어떻게 될까요?
이때는 수량 우선 원칙이 적용되게 되는데요, 주문 수량이 많은 사람이 우선한다는 원칙입니다.
다음과 같은 상황을 가정해 보겠습니다. A,B,C 모두 같은 시각에 매도 주문을 내었고, 갑과 을도 같은 시간에 매수 주문을 내었습니다.

    - A: 한주당 8,000원 100주 매도 주문,
    - B: 한주당 8,000원 50주 매도 주문,
    - C: 한주당 8,000원 70주 매도 주문,
    - 갑: 한주당 10,000원 100주 매수 주문,
    - 을: 한주당 10,000원 10주 매수 주문

매도자들이 서로 같은 가격으로 주문을 했고 매수자들도 같은 매수 가격을 제시했으니, 가격 우선 체결 원칙은 적용될 수 없고, 또 같은 시각에 주문을 내었으니 시간 우선 원칙도 적용될 수 없습니다.
이 경우에는 수량 우선 주식 체결 원칙에 따라 거래가 이루어 집니다. 주문 수량이 많은 순으로 우선 순위가 정해 지므로 매도자는 A → C → B, 매수자는 갑 → 을 순으로 우선 순위를 갖게 됩니다.
따라서 갑은 A에게서 100주를 주당 10,000원으로 매수하게 되고, 을은 C로부터 주당 10,000원으로 10주를 매수하게 됩니다.
B는 한 주도 팔지 못하고 C는 70주 중에서 10주만 매도에 성공하게 됩니다.
이상 정규 시장에서의 주식 체결 순서였습니다. 이제 동시호가 시간의 주식 체결은 어떻게 이루어 지는 지 알아 보겠습니다.

동시호가 시간엔 모두 거래가 동시에 이루어 졌다고 가정하여 주식 체결

동시호가 시간은 오전 8시에서 오전 9시까지(장전 동시호가) 한 시간 또 오후 2시 50분에서 오후 3시까지(장 마감 동시호가) 10분간 이루어 집니다.
이 시간에 이루어 지는 매도·매수 주문은 모두 동시에 이루어 진 것으로 간주합니다. 동시(同時)호가라는 이름은 그래서 생긴 것이죠.
어쨌든 이 원칙에 따르면 오전 8시에 낸 주문도 오전 8시 50분에 낸 주문도 같은 시간에 이루어 진 것으로 간주하게 됩니다.
따라서 동시호가 시간의 주식 매매에는 시간 우선 원칙을 적용할 수 없습니다. 가격 우선 원칙을 먼저 적용하고 그 다음에 수량 우선 원칙을 적용하게 되죠.
그런데 일정 시간 동안에 있었던 주식 매매 주문을 같은 시간에 이루어 진 것으로 간주할 경우 , 일정 시점을 끊어서 거래를 체결해 주어야 합니다. 그렇지 않으면 거래가 이루어지지 않겠지요.
그래서 장전 동시호가 시간에 있었던 주문들은 오전 9시에 동시에 이루어 진 것으로 보아 일괄적으로 체결하고 장 마감 동시호가 시간에 있었던 주문들은 오후 3시에 일괄적으로 체결 됩니다.

시초가와 종가

잠시 후에 동시호가 시간의 주식 체결 방식을 구체적으로 알아 볼텐데요, 동시호가 주식 체결 방식에 따라 결정된 주식 가격은 특별한 의미를 가집니다.
즉, 장전 동시호가에서 결정된 주식 가격은 시초가가 되고 장마감 동시호가에서 결정된 주식 가격은 그날의 종가가 됩니다.
어떻게 시초가와 종가가 결정 되는 지는 아래에서 예를 들어 알아 보겠습니다.

동시호가 주식 체결 방식

동시호가 시간에 있었던 주문은 모두 같은 시간에 한 것으로 간주하고 가격 우선 → 수량 우선 체결 원칙이 적용 된다고 했는데요, 정규 시장과 다른 점이 한 가지 더 있습니다.
동시호가 시간의 주문은 가격 우선과 수량 우선 순서로 적용하되 모든 주문을 한꺼번에 체결 하기 때문에 마지막으로 성립되는 거래에서 매수자가 제시한 가격으로 일괄 체결된다는 점이 다릅니다.
아마 말로는 쉽게 이해되지 않을 것 같은데요, 아래의 예를 보면 금방 이해할 수 있습니다.
동시호가 시간 동안 어떤 주식에 대해 매도자와 매수자가 다음과 같이 주문을 했다고 가정해 보겠습니다.

    매도자
    - A: 주당 10,000원에 100주
    - B: 주당 10,100원에 10주
    - C: 주당 10,200원에 30주
    매수자
    - 갑: 주당 10,300에 70주
    - 을: 주당 10,150에 30주
    - 병: 주당 10,150에 50주

가격 → 수량 우선 순서에 따라 매도자는 A → B → C 순으로 우선 순위를 가지고, 매수자는 갑 → 병 → 을 순으로 우선 순위를 가지게 됩니다.
일단 갑과 A 사이에 70주 거래가 가능합니다.

그 다음 우선 순위인 병은 A로부터 30주를 살 수 있고 B로부터 10주를 살 수 있습니다. 여기까지의 상황은 A와 B가 주문을 낸 만큼 모두 팔 수 있고, 갑은 원하는 수만큼 모두 구매 할 수 있으며 병은 원하는 수량 50주 중 40주를 매수할 수 있는 상황입니다.
병이 나머지 10주를 매수하기 위해서는 C로부터 매수해야 하는데 C는 10,200원에 팔기를 원하고 병은 10,150에 매수하기를 원하므로 거래가 성립되지 않습니다.
따라서 마지막으로 성립된 거래는 병과 B사이의 거래고 이 때의 매수 가격은 10,150원입니다. 위 예가 장전 동시호가라면 10,150원이 시초가가 될 것이고 장 마감 동시호가라면 10,150원이 종가가 됩니다.
정규시장이었다면, 갑과 A 사이는 10,300원으로 거래가 되겠지만, 동시호가 시간의 거래 원칙에 따라 갑과 A 사이도 최종 거래 가격인 10,150원으로 거래가 됩니다. 이제 ‘동시호가 시간의 거래는 마지막으로 성립되는 거래에서 매수자가 제시한 가격으로 일괄 체결 된다.’는 말을 이해할 수 있을 것입니다.

장전 동시호가시간 거래할 때 주의할 점

회사 출근 때문에 HTS나 MTS를 이용할 수 없는 직장인이나 비슷한 이유로 장중에 주식 매매를 할 수 없는 경우 오전 8시 ~ 오전 9시 사이에 미리 주문을 내어 놓는 경우가 있습니다.
동시호가 주식 체결 방식에 따라 거래가 성립된다면 9시에 일괄적으로 체결되지만, 자신이 낸 주문이 체결 되지 않았다면 어떻게 될 까요?
장 마감 동시호가 시간에 낸 주문이 체결되지 않는 경우에는 오후 3시에 자동으로 취소가 됩니다만, 장전 동시호가 시간에 낸 주문이 체결 되지 않는 경우는 자동으로 취소가 되지 않습니다.
따라서 체결 되지 않은 (장전 동시호가 시간에 낸) 주문은 오전 9시에 취소 주문을 하는 것이 좋습니다.
물론 주문 내용 그대로 장 중에 매매가 되기를 희망한다면 굳이 취소 주문을 한 후 새로 주문을 낼 필요가 없지만,
주식이라는 것이 장전 분위기와 장 시작한 후의 분위기가 다른 때가 많은 법이니 장전 동시호가 시간에 내었던 주문은 꼭 체결 되었는지 여부를 확인하고 체결되지 않았다면 필요한 조치(그대로 두거나, 취소 주문을 내거나, 아니면 취소 주문후 새로운 조건으로 주문을 내 는 조치)를 취해야 한다는 점을 잊지 마시기 바랍니다.

시간외 거래

시간외 거래는 시간외 종가 매매와 시간외 단일가 매매로 나뉘어 지는데요, 시간외 종가 매매는 전일 종가로만 거래되는 장전 시간외 거래 시간(오전 7시 30분 ~ 오후 8시 30분)와 당일 종가로만 거래되는 장후 시간외 거래 시간(오후 3시 ~ 오후 3시 30분)으로 나누어 집니다.
장후 시간외 거래의 경우는 오후 3시부터 주문을 할 수는 있지만 체결은 오후 3시 10분부터 이루어 집니다.
시간외 단일가 매매는 오후 3시 30분~ 오후 6시 사이에 이루어 지는데요, 당일 종가 기준 ±5% 범위에서 매수 매도 주문을 낼 수 있습니다.
단, 상한가와 하한가를 초과할 수는 없기 때문에 상한가로 마감된 경우에는 상한가~상한가-5%, 하한가로 마감된 경우에는 하한가 ~ 하한가+5% 범위에서 주문을 낼 수 있습니다.
시간외 단일가 매매 체결은 오후 4시 ~ 오후 6시 사이에 10분 단위로 동시호가 방식으로 이루어 집니다.
시간외 거래 주문은 동시호가나 정규장 시간에 이용하는 창이 아니라 별도의 창(증권사에 따라서는 주문 종류 선택으로 하는 곳도 있음)에서 해야 합니다.

주식 체결 순서에 대한 결론

지금까지 정규 주식 시장, 동시호가 시간, 시간외 거래 시간에 주식이 체결 되는 방식에 대해 알아 보았는데요,
주식 체결 순서 원칙은 정규 시장에서 이루어 지는 가격 → 시각 → 수량 우선 원칙입니다. 동시호가 시간과 시간외 거래는 이 원칙의 변용으로 이해하면 됩니다.
체결 순서 기본 원칙에 따라 매도자 입장에서 빨리 매도에 성공하려면 가능한 한 낮은 가격으로 빨리 또 가능한 많은 수량의 주문을 내야 하고 매수자 입장이라면 가능한 한 높은 가격으로 최대한 빨리 많은 수량의 주문을 내야 한다는 것을 알 수 있습니다.
그런데 매도자 입장에서는 최대한 높은 가격으로 팔고 매수자 입장에서는 될 수 있는 한 낮은 가격으로 주식 거래를 체결해야 이익입니다. 가격 우선 체결 원칙은 이와는 반대로 가죠.
시간 우선 체결 원칙 상황도 비슷합니다. 빨리 거래를 성공시키기 위해서는 빨리 주문을 내야 하지만, 주식 투자라는 것이 간을 보아야 할 때가 많습니다.
수량 우선 상황도 비슷하죠. 많은 수량으로 주문을 내야 빨리 거래를 성공 시킬 수 있지만, 보유 주식을 한꺼번에 매도 하는 것보다는 분할 매도 하는 것이 또 분할 매수 하는 것이 일반적인 주식 투자 원칙입니다.
이처럼 주식 체결 순서 원칙은 주식 투자를 통해 수익를 얻으려는 목적과 반대되는 경향이 있다는 점을 염두에 두시기 바랍니다.
물론 주식 투자를 하다 보면 최대한 빨리 팔거나 사야 할 때가 있고 이 때는 주식 체결 순서를 고려하여 주문을 내야 하지만, 그렇지 않은 상황에서는 사실 주식 체결 순서를 그리 민감하게 고민할 필요는 없다는 말씀입니다.
주식 체결 순서 원칙보다는 자신만의 투자 원칙에 집중하는 것이 더 좋다는 생각입니다.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>

#include "tagwire.h"
#include "fssdefine.h"

#define HEADERINDEX 13

int main(int argc, char *argv[])
{
FILE *fp=NULL;
char rbuf[4096 * 2L];

if(argc != 2) return -1;

if((fp=fopen(argv[1], "rt"))==NULL) return -1;

while(1)
{
memset(rbuf, 0x00, sizeof(rbuf));
if(fgets(rbuf, sizeof(rbuf), fp)==NULL) break;
rbuf[strlen(rbuf)-1]=0x00;

        if(memcmp(rbuf+HEADERINDEX,"296=",4)==0)
{
struct TradableInstrument *ie=NULL;

ie = TradableInstrument(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.4s],", rbuf+HEADERINDEX);
printf("shortName:[%s],", ie->shortName);
printf("orderBookId:[%ld],", ie->orderBookId);
printf("closingPrice:[%ld],", ie->closingPrice);
printf("isDeleted:[%c],", ie->isDeleted);
printf("upperPriceLimit:[%ld],", ie->upperPriceLimit);
printf("lowerPriceLimit:[%ld],", ie->lowerPriceLimit);
printf("closingDate:[%s]", ie->closingDate);

printf("\n");
}
}
else if(memcmp(rbuf+HEADERINDEX,"496=",4)==0)
{
struct IndexEvent *ie=NULL;

ie = IndexEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.4s],", rbuf+HEADERINDEX);
printf("sequenceNumber[%ld],", ie->sequenceNumber);
printf("timeOfEvent[%s]", ie->timeOfEvent);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"140=",3)==0)
{
struct MarketByLevelEvent *ie=NULL;

ie = MarketByLevelEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent[%s],",ie->timeOfEvent);
printf("orderBook[%ld],",ie->orderBook);
printf("isBid[%c],",ie->isBid);
printf("price[%ld],",ie->price);
printf("volume[%ld],",ie->volume);
printf("correspondingPrice[%ld]",ie->correspondingPrice);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"51=",3)==0)
{
struct OrderBookStateChangeEvent *ie=NULL;

ie = OrderBookStateChangeEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent:[%s],", ie->timeOfEvent);
printf("orderBookRuleGroup:[%s]", ie->orderBookRuleGroup);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"49=",3)==0)
{
struct TradeEvent *ie=NULL;

ie = TradeEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfTrade[%s],", ie->timeOfTrade);
printf("orderQty[%ld],", ie->orderQty);
printf("price[%ld],", ie->price);
printf("highPrice[%ld],", ie->highPrice);
printf("lowPrice[%ld],", ie->lowPrice);
printf("totalTurnover[%ld],", ie->totalTurnover);
printf("correspondingPrice[%ld],", ie->correspondingPrice);
printf("tradeId[%s],", ie->tradeId);
printf("dealId[%s]", ie->dealId);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"62=",3)==0)
{
struct AuctionEvent *ie=NULL;

ie = AuctionEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent[%s],",ie->timeOfEvent);
printf("orderBook[%ld],",ie->orderBook);
printf("calculatedAuctionPrice[%ld],",ie->calculatedAuctionPrice);
printf("matchedQuantity[%ld]",ie->matchedQuantity);

printf("\n");
}
}
}
if(fp != NULL) fclose(fp);
return(0);
}

TCP는 데이터 순서 보장을 위해 한 번에 하나의 Packet만 수신할까?

정답은 X입니다.
많은 데이터를 매번 ACK를 받고 보내기엔 너무 많은 Cost가 필요합니다.
위와 같은 문제를 해결하기 위해 window라는 논리적인 패킷 묶음을 사용합니다.
최소한의 ACK로 데이터 순서를 보장하며 전송을 할 수 있습니다.

 

 

참조문서 내용일부)

Receive socket buffer 크기가 결국은 TCP의 receive window이다. 어느 지점까지는 receive window가 크면 TCP throughput이 증가한다. 예전에는 socket buffer 크기를 애플리케이션이나 운영체제 설정에서 조절하고는 했다. 최신 네트워크 스택은 receive socket buffer 크기, 즉 receive window를 자동으로 조절하는 기능을 가지고 있다.

이후 애플리케이션이 read 시스템 콜을 호출하면 커널 영역으로 전환되고, socket buffer에 있는 데이터를 유저 공간의 메모리로 복사해 간다. 복사한 데이터는 socket buffer에서 제거한다. 그리고 TCP를 호출한다. TCP는 socket buffer에 새로운 공간이 생겼기 때문에 receive window를 증가시킨다. 그리고 프로토콜 상태에 따라 패킷을 전송한다. 패킷 전송이 없으면 시스템 콜이 종료된다.

 


참조)
https://d2.naver.com/helloworld/47667

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str = "ffffffaaaabcccddeeeeeffffgghijklmmmmnnnnopppqrstuuuuuvwxxxxxyyyyz";

int index[strlen(str)][2];

int kk, ff;

memset(index,0x00,sizeof(index));

    for(kk=0; kk<strlen(str); kk++)
{
index[kk][0] = *(str+kk);
}

    for(ff=0; ff<strlen(str); ff++)
{
    for(kk=0; kk<strlen(str); kk++)
    {
        if(index[ff][0] == index[kk][0]) index[ff][1]++;
}
}

for(kk=0; kk<strlen(str); kk++)
{
if(index[kk][1] ==1)
printf("[%c]>>>>[%d]\n", index[kk][0], index[kk][1]);
}


return(0);
}


/*
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\SIHOO\Downloads\example>__11
[b]>>>>[1]
[h]>>>>[1]
[i]>>>>[1]
[j]>>>>[1]
[k]>>>>[1]
[l]>>>>[1]
[o]>>>>[1]
[q]>>>>[1]
[r]>>>>[1]
[s]>>>>[1]
[t]>>>>[1]
[v]>>>>[1]
[w]>>>>[1]
[z]>>>>[1]
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str = "ffffffaaaabcccddeeeeeffffgghijklmmmmnnnnopppqrstuuuuuvwxxxxxyyyyz";

int kk, ff;

    if(strlen(str) > 3)
{
kk=0;
if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

for(kk=1; kk<strlen(str) -1; kk++)
{
if(*(str+kk) == *(str+kk+1)) continue;
if(*(str+kk) == *(str+kk-1)) continue;

printf("%c", *(str+kk));
}
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else
{
if(strlen(str) == 3)
{
kk=0;
     if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

kk++;

ff=0;
if(*(str+kk) == *(str+kk+1)) ff=100;
if(*(str+kk) == *(str+kk-1)) ff=100;
if(ff==0)
{
printf("%c", *(str+kk));
}

kk++;
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else if(strlen(str) == 2)
{
kk=0;
     if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

kk++;
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else
{
kk=0;
printf("%c", *(str+kk));
}
}

return(0);
}

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <string.h>

 

#define MAXLINE 9999
#define MAX_SOCK 128

 

int main(int argc, char *argv[]) 
{
FILE *fp=NULL;

char line[MAXLINE], message[MAXLINE+1], filename[MAXLINE+1];
struct sockaddr_in server_addr;
int maxfdp1;
int ____socket; /* 서버와 연결된 소켓번호 */
fd_set read_fds;

int kk=0;

 

if (argc != 4) {

printf("Usage : %s server_ip port filename\n", argv[0]);

printf("%s 127.0.0.1 12572 /usr2/suksu/ftp/BATCH_A0011.dat\n", argv[0]);

exit(0);
}

 

sprintf(filename, "%s", argv[3]);
if((fp=fopen(filename, "rt"))==NULL) exit(0);

/* 소켓 생성 */
if ((____socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Client: Can't open stream socket.\n");
exit(0);
}

 

/* 채팅 서버의 소켓주소 구조체 server_addr 초기화 */
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));

/* 연결요청 */
if (connect(____socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Client: Can't connect to server.\n");
exit(0);

else 
{
    printf("Connected with server succ!!\n");
}

while (1) 
{
memset(line,0x00,sizeof(line));
if(fgets(line,sizeof(line),fp)==NULL) break;

line[strlen(line)-1]=0x00;

if (send(____socket, line, strlen(line), 0) < 0) 
{
printf("Client: Write error on socket.\n");
break;
}
//printf("%s\n", line);

usleep(4444);
kk++;
}

close(____socket);
if(fp != NULL) fclose(fp);

printf("FileName[%s] :[%05d]\n", filename, kk);
}

 

 

 

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <string.h>

#define MAXLINE 99999
#define MAX_SOCK 64

int getmax(int);
void disconnect_client(int); /* 채팅 탈퇴 처리 함수 */
void my_signal(int signo); /* 새로운 시그널 처리 함수 선언 */

int maxfdp1;            /* 최대 소켓번호+1 */
int num_chat = 0;       /* 채팅 참가자 수 */
int ____main_socket;                  /* 초기 소켓 */
int ____client_socket[MAX_SOCK]; /* 채팅에 참가자 소켓번호 목록 */

int main(int argc, char *argv[]) 
{
char rline[MAXLINE+1];
int i, j, kk;
int recv_len;
int client_fd, clilen;

int recv_len_sum=0;
int recv_seq_sum=0;
int recv_divide;


fd_set read_fds; /* 일기 감지할 소켓번호 구조체 */
struct sockaddr_in client_addr, server_addr;

if (argc != 2) {
printf("Usage: %s port\n", argv[0]);
exit(0);
}

/* 초기소켓 생성 */
if ((____main_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Server: Can't open stream socket.");
exit(0);
}

/* server_addr 구조체의 내용 세팅 */
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));

if (bind(____main_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Server: Can't bind local address.\n");
exit(0);
}

if (signal(SIGINT, my_signal) == SIG_ERR) { /* Ctrl+C */
printf("Server: signal(SIGINT) error\n");
exit(0);
}
if (signal(SIGTERM, my_signal) == SIG_ERR) { /* software termination */
printf("Server: signal(SIGTERM) error\n");
exit(0);
}
if (signal(SIGQUIT, my_signal) == SIG_ERR) { /* Ctrl+\ */
printf("Server: signal(SIGQUIT) error\n");
exit(0);
}


/* 클라이언트로부터 연결요청을 기다림 */
listen(____main_socket, 5); /* backlog = 5 */

maxfdp1 = ____main_socket + 1; /* 최대 소켓번호+1 */

while (1) 
{
FD_ZERO(&read_fds);
FD_SET(____main_socket, &read_fds);
for (kk=0; kk < num_chat; kk++)
{
    FD_SET(____client_socket[kk], &read_fds);
}

maxfdp1 = getmax(____main_socket) + 1; /* maxfdp1 재 계산 */

if (select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("Server: select error <= 0\n");
break;
}

if (FD_ISSET(____main_socket, &read_fds)) 
{
clilen = sizeof(client_addr);
client_fd = accept(____main_socket, (struct sockaddr *)&client_addr, &clilen);
if (client_fd == -1) 
{
    printf("Server: accept error\n");
    break;
    }

    ____client_socket[num_chat] = client_fd;
    num_chat++;
}

for (kk=0; kk < num_chat; kk++) 
{
if (FD_ISSET(____client_socket[kk], &read_fds)) 
{
if ((recv_len = recv(____client_socket[kk], rline, MAXLINE, 0)) <= 0) 
{
disconnect_client(kk); /* abrupt exit */
continue;
}
rline[recv_len] = '\0';

            recv_divide = recv_len / getfromframeid(rline, recv_len);
recv_seq_sum++;
recv_len_sum = recv_len_sum + recv_divide;

printf("SESSION SEQ[%07d]/RECV LENGTH[%07d]/DIVIDE[%07d]/REAL SUM[%07d]/SEQ SUM[%07d]\n", 
                                        kk+1, recv_len,
recv_divide, recv_len_sum, recv_seq_sum);
}
}
} /* while */
my_signal(SIGIO);
}

/* 채팅 탈퇴 처리 */
void disconnect_client(int i) {
struct sockaddr_in client_addr;

close(____client_socket[i]);
if (i != num_chat-1)
____client_socket[i] = ____client_socket[num_chat-1];
num_chat--;

printf("[function]disconnect_client>>[%d]\n", num_chat);
}

/* ____client_socket[] 내의 최대 소켓번호 얻기(초기치는 k) */
int getmax(int k) {
int max = k;
int r;
for (r=0; r < num_chat; r++)
if (____client_socket[r] > max)
max = ____client_socket[r];
return max;
}

/* 시그널 처리 함수 정의 */
void my_signal(int signo) {
int i;

signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGQUIT, SIG_IGN);

/* 모든 열려있는 소켓을 닫는다 */
close(____main_socket);
for (i=0; i < num_chat; i++)
close(____client_socket[i]);

exit(0);
}

int getfromframeid(char *tmp, int len)
{
int kk=0;

if(memcmp(tmp, "A0011", 5) == 0) kk=800;

return kk;
}


extern char design[6][2+1];
extern int ____hexa[MAPY][MAPX];
extern int hexa[MAPY][MAPX];

 

 

 

void gotoxy(int x, int y)
{
    COORD Pos = {x - 1, y - 1};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void f_display_all(void)
{
    int i, k;

    for(i=0; i<MAPY; i++)
    {
        for(k=0; k<MAPX; k++)
        {
            if(hexa[i][k] == 10)
            {
                continue;
            }
            else if(hexa[i][k] == 0)
            {

                gotoxy(k * 2 + 1, i + 2);
                printf("□");

            }
            else
            {
               gotoxy(k * 2 + 1, i + 2);
               printf("%s", design[ hexa[i][k] ]);
            }
        }
    }


#if(1)
for(i=0; i<MAPY; i++)
    {
        for(k=0; k<MAPX; k++)
        {
____hexa[i][k] = hexa[i][k];
}
}
#endif
}

void f_display(int x, int y)
{
    int i, k;

#if(1)
    for(i=0; i<MAPY; i++)
    {
        for(k=0; k<MAPX; k++)
        {
            if(hexa[i][k] == 10)
            {
                continue;
            }
else if(hexa[i][k] == ____hexa[i][k]) continue;
            else if(hexa[i][k] == 0)
            {

                gotoxy(k * 2 + 1, i + 2);
                printf("□");

            }
            else
            {
               gotoxy(k * 2 + 1, i + 2);
               printf("%s", design[ hexa[i][k] ]);
            }
        }
    }
#endif

#if(1)
for(i=0; i<MAPY; i++)
    {
        for(k=0; k<MAPX; k++)
        {
____hexa[i][k] = hexa[i][k];
}
}
#endif
}

#if(1)
    if(____type==0)  //처음 한번은 전체출력으로 하고, 다음부터는 변한부분만 출력하도록 한다.
{
        for(i=0; i<MAPY; i++)
{
            for(k=0; k<MAPX; k++)
                {
if(hexa[i][k] == 10)
{
continue;
}
else if(hexa[i][k] == 0)
{
TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, "□", 2);
}
else
{
TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, design[ hexa[i][k] ], 2);
}
}
}
____type=1;
}
else
{
for(i=0; i<MAPY; i++)
{
for(k=0; k<MAPX; k++)
{
if(hexa[i][k] == ____hexa[i][k]) continue;
else if(hexa[i][k] == 0)
{
TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, "□", 2);
}
else
{
TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, design[ hexa[i][k] ], 2);
}
}
}
}
#endif

#include <time.h>
struct tm *localtime_r(const time_t *timep, struct tm *result);



----DESCRIPTION
localtime_r 함수는 time_t type의 초단위의 시간을 지역시간(locale정보)의 struct tm type으로 변환하는 함수입니다.
localtime()함수가 변환된 결과를 local static변수에 저장하는것과 달리 localtime_r()함수는 data를 변환한 결과값을
result에 저장하기때문에 multi-thread에서도 안전한 thread-safe함수입니다.





#include <time.h>
#include <stdio.h>

struct tm *localtime_r(const time_t *timep, struct tm *result);

int main(int argc, char **argv[])
{
    time_t t;
    struct tm lt;
 
    if((t=time(NULL))==-1) {
        printf("time() call error\n");
        return -1;
    }
    if(localtime_r(&t, &lt)==NULL) {
        printf("localtime_r() call error\n");
        return -1;
    }
    printf("NOW TIME:%04d-%02d-%02d %02d:%02d:%02d\n",
    lt.tm_year + 1900,
    lt.tm_mon + 1,
    lt.tm_mday,
    lt.tm_hour,
    lt.tm_min,
    lt.tm_sec);
 
    return 0;

/* 

 * printf에서 자주사용되고, 유용한 *에 대해서 알아본다.

 * printf에서 자주사용되고, 유용한 *에 대해서 알아본다.

 * printf에서 자주사용되고, 유용한 *에 대해서 알아본다.

 */

 

#include <stdio.h>

 

struct TESTSCORE_ST

{

    char Number[5];

    char Name[20];

char KorScore[10];

char EngScore[10];

char MathScore[10];

};

 

//구조체변수 초기화및 데이타 세팅하기

struct TESTSCORE_ST score[7] = {

{"1001", "Park", "90.2", "65.43", "56.99"},

{"1002", "Lee", "90.2", "65.43", "56.99"},

{"1003", "Choi", "90.2", "65.43", "56.99"},

{"1004", "Jung", "90.2", "65.43", "56.99"},

{"1005", "Son", "90.2", "65.43", "56.99"},

{"1006", "Nam", "90.2", "65.43", "56.99"},

{"1007", "Kim", "90.2", "65.43", "56.99"} };

 

int main(void)

{

    int kk;

 

for(kk=0; kk<7; kk++)

{

        //LEFT정렬,ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

        printf("[%-*s]"

           "[%-*s]"

          "[%-*s]"

   "[%-*s]"

   "[%-*s]",

      sizeof(score[kk].Number), score[kk].Number,

      sizeof(score[kk].Name), score[kk].Name,

      sizeof(score[kk].KorScore), score[kk].KorScore,

      sizeof(score[kk].EngScore), score[kk].EngScore,

      sizeof(score[kk].MathScore), score[kk].MathScore);

printf("\n");

        //RIGHT정렬,,ㅡㅡㅡㅡㅡㅡㅡㅡ

printf("[%*s]"

        "[%*s]"

       "[%*s]"

       "[%*s]"

       "[%*s]",

      sizeof(score[kk].Number), score[kk].Number,

      sizeof(score[kk].Name), score[kk].Name,

      sizeof(score[kk].KorScore), score[kk].KorScore,

      sizeof(score[kk].EngScore), score[kk].EngScore,

      sizeof(score[kk].MathScore), score[kk].MathScore);

printf("\n");

printf("[%s]"

           "[%s]"

   "[%s]"

   "[%s]"

          "[%s]",

      score[kk].Number,

      score[kk].Name,

      score[kk].KorScore,

      score[kk].EngScore,

      score[kk].MathScore);

        printf("\n");

}

return 0;

}

 

/*RESULT

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Corporation. All rights reserved.

 

[1001 ][Park                ][90.2      ][65.43     ][56.99     ]

[ 1001][                Park][      90.2][     65.43][     56.99]

[1001][Park][90.2][65.43][56.99]

[1002 ][Lee                 ][90.2      ][65.43     ][56.99     ]

[ 1002][                 Lee][      90.2][     65.43][     56.99]

[1002][Lee][90.2][65.43][56.99]

[1003 ][Choi                ][90.2      ][65.43     ][56.99     ]

[ 1003][                Choi][      90.2][     65.43][     56.99]

[1003][Choi][90.2][65.43][56.99]

[1004 ][Jung                ][90.2      ][65.43     ][56.99     ]

[ 1004][                Jung][      90.2][     65.43][     56.99]

[1004][Jung][90.2][65.43][56.99]

[1005 ][Son                 ][90.2      ][65.43     ][56.99     ]

[ 1005][                 Son][      90.2][     65.43][     56.99]

[1005][Son][90.2][65.43][56.99]

[1006 ][Nam                 ][90.2      ][65.43     ][56.99     ]

[ 1006][                 Nam][      90.2][     65.43][     56.99]

[1006][Nam][90.2][65.43][56.99]

[1007 ][Kim                 ][90.2      ][65.43     ][56.99     ]

[ 1007][                 Kim][      90.2][     65.43][     56.99]

[1007][Kim][90.2][65.43][56.99]

----------------------------------------------------------------------------*/

 

 

 

   

mysql> select @r:=@r+1 As rowNum, T2.t_regtime,T2.t_cnt from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2, (Select @r:=0)r;
+--------+-------------------+-------+
| rowNum | t_regtime         | t_cnt |
+--------+-------------------+-------+
|      1 | 20190829 12:42:03 |   669 |
|      2 | 20190829 12:42:04 |  3021 |
|      3 | 20190829 12:42:05 |  5429 |
|      4 | 20190829 12:42:06 |  5005 |
|      5 | 20190829 12:42:07 |  3661 |
|      6 | 20190829 12:42:08 |  3310 |
|      7 | 20190829 12:42:09 |  2807 |
|      8 | 20190829 12:42:10 |  3950 |
|      9 | 20190829 12:42:11 |  4715 |
|     10 | 20190829 12:42:12 |  5130 |
|     11 | 20190829 12:42:13 |  4318 |
|     12 | 20190829 12:42:14 |  2918 |
|     13 | 20190829 12:42:15 |  2980 |
|     14 | 20190829 12:42:16 |  4156 |
|     15 | 20190829 12:42:17 |  5870 |
|     16 | 20190829 12:42:18 |  5236 |
|     17 | 20190829 12:42:19 |  5546 |
|     18 | 20190829 12:42:20 |  5367 |
|     19 | 20190829 12:42:21 |  3181 |
|     20 | 20190829 12:42:22 |  2807 |
|     21 | 20190829 12:42:23 |  2554 |
|     22 | 20190829 12:42:24 |  1379 |
|     23 | 20190829 12:42:25 |  4924 |
|     24 | 20190829 12:42:26 |  4724 |
|     25 | 20190829 12:42:27 |  5641 |
|     26 | 20190829 12:42:28 |  5661 |
|     27 | 20190829 12:42:29 |  3936 |
|     28 | 20190829 12:42:30 |  3557 |
|     29 | 20190829 12:42:31 |  4186 |
|     30 | 20190829 12:42:32 |  4821 |
|     31 | 20190829 12:42:33 |  4621 |
|     32 | 20190829 12:42:34 |  4697 |
|     33 | 20190829 12:42:35 |  3264 |
|     34 | 20190829 12:42:36 |  3706 |
|     35 | 20190829 12:42:37 |  2423 |
|     36 | 20190829 12:42:38 |  2043 |
|     37 | 20190829 12:42:39 |  4207 |
|     38 | 20190829 12:42:40 |  3524 |
|     39 | 20190829 12:42:41 |  4656 |
|     40 | 20190829 12:42:42 |  3582 |
|     41 | 20190829 12:42:43 |  2995 |
|     42 | 20190829 12:42:44 |   120 |
+--------+-------------------+-------+
42 rows in set (0.25 sec)

mysql>


 

다음과 같은 테이블이 존재한다. (테이블명 : ISS_HH)

SEQ_NO(PK) USER_ID INFO1 INFO2
1 10001 HH KK
2 10002 HH KK
3 10003 HH KK
4 10004 HH KK
5 10005 HH KK
6 10006 HH KK
7 10007 HH KK
8 10008 HH KK
9 10009 HH KK
10 10010 HH KK
11 10011 HH KK
12 10012 HH KK

 

위의 SEQ_NO를 1씩 증가시키기 위해서는 보통 아래와 같은 SQL을 생각하기 쉽다.

 

SQL>UPDATE ISS_HH SET SEQ_NO = SEQ_NO + 1 WHERE USER_ID > 10000

 

그러나 위를 실행하면, DUPLICATE ERROR가 발생한다. 이유는 멀까? 

 

PK인 SEQ_NO에 UPDATE시에 데이타가 중복으로 발생하게 된다. 즉 이런 경우는 가장큰 SEQ_NO를 증가시키는것이 일반적이다.

 

>>>>>>>>>OK QUERY

SQL>UPDATE ISS_HH SET SEQ_NO = SEQ_NO + 1 WHERE USER_ID > 10000 ORDER BY SEQ_NO DESC

 

-1 을 할경우는 반대로 생각하면 된다.

SQL>UPDATE ISS_HH SET SEQ_NO = SEQ_NO -1 WHERE USER_ID > 10000 ORDER BY SEQ_NO ASC

 

 

비고) 한번에 처리하지 않고, 하나씩 처리하는 프로그램으로 작성해보라,ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

비고) 한번에 처리하지 않고, 하나씩 처리하는 프로그램으로 작성해보라,ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

비고) 한번에 처리하지 않고, 하나씩 처리하는 프로그램으로 작성해보라,ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

비고) 한번에 처리하지 않고, 하나씩 처리하는 프로그램으로 작성해보라,ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

 

 

1. RB_OCUS_POS_TEST2테이블에 200,00개의 데이타를 넣는다.

2. 1초에 3,000개 이상의 데이타가 들어가는 횟수를 알고 싶다면?

3. 아래는 위의 문제를 구하기 위해서 구성한 쿼리이다.

 

 

mysql> show create table RB_OCUS_POS_TEST2;
+-------------------+-----------------------------------
| Table             | Create

+-------------------+-----------------------------------
| RB_OCUS_POS_TEST2 | CREATE TABLE `RB_OCUS_POS_TEST2` (
  `seqno` int(11) NOT NULL,
  `account_no` varchar(10) NOT NULL,
  `stock_symbol` varchar(20) NOT NULL,
  `start_volume` varchar(10) DEFAULT NULL,
  `start_amount` varchar(13) DEFAULT NULL,
  `start_price` varchar(13) DEFAULT NULL,
  `stock_type` varchar(2) DEFAULT NULL,
  `trustee_id` varchar(2) DEFAULT NULL,
  `regtime` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`seqno`,`account_no`,`stock_symbol`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------------------+-----------------------------------
1 row in set (0.00 sec)

mysql>

mysql> desc RB_OCUS_POS_TEST2;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| seqno        | int(11)     | NO   | PRI | NULL    |       |
| account_no   | varchar(10) | NO   | PRI | NULL    |       |
| stock_symbol | varchar(20) | NO   | PRI | NULL    |       |
| start_volume | varchar(10) | YES  |     | NULL    |       |
| start_amount | varchar(13) | YES  |     | NULL    |       |
| start_price  | varchar(13) | YES  |     | NULL    |       |
| stock_type   | varchar(2)  | YES  |     | NULL    |       |
| trustee_id   | varchar(2)  | YES  |     | NULL    |       |
| regtime      | varchar(30) | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
9 rows in set (0.00 sec)

mysql>

mysql> select * from RB_OCUS_POS_TEST2 limit 10;
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
| seqno | account_no | stock_symbol         | start_volume | start_amount  | start_price   | stock_type | trustee_id | regtime                |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
|     1 | 0016100    | BBL                  | 0000001500   | 0000266962.22 | 000177.974813 | 02         |            | 20190828 11:19:25(140) |
|     2 | 0016100    | BPP                  | 0000002000   | 0000042000.00 | 000021.000000 | 02         |            | 20190828 11:19:25(141) |
|     3 | 0016100    | CK                   | 0000015375   | 0000296816.51 | 000019.305139 | 02         |            | 20190828 11:19:25(142) |
|     4 | 0016100    | IEC                  | 0012286603   | 0000308909.54 | 000000.025142 | 02         |            | 20190828 11:19:25(142) |
|     5 | 0016100    | IVL                  | 0000011769   | 0000309729.03 | 000026.317362 | 02         |            | 20190828 11:19:25(142) |
|     6 | 0016100    | KTB                  | 0000005000   | 0000103785.51 | 000020.757102 | 02         |            | 20190828 11:19:25(142) |
|     7 | 0055920    | ASAP                 | 0000001000   | 0000003106.87 | 000003.106870 | 02         |            | 20190828 11:19:25(142) |
|     8 | 0055920    | BCP                  | 0000001000   | 0000033574.22 | 000033.574220 | 02         |            | 20190828 11:19:25(142) |
|     9 | 0055920    | CBG                  | 0000000800   | 0000042844.70 | 000053.555875 | 02         |            | 20190828 11:19:25(143) |
|    10 | 0055920    | CHAYO                | 0000002000   | 0000008739.30 | 000004.369650 | 02         |            | 20190828 11:19:25(143) |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+------------------------+
10 rows in set (0.00 sec)

mysql>

mysql> select T2.t_cnt from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2 limit 10;
+-------+
| t_cnt |
+-------+
|  2149 |
|  2556 |
|  3462 |
|  2635 |
|  2780 |
|  3051 |
|  2450 |
|  2310 |
|  2695 |
|  2716 |
+-------+
10 rows in set (0.22 sec)

mysql> 
mysql> select T2.t_cnt from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2 where T2.t_cnt > 3000;
+-------+
| t_cnt |
+-------+
|  3462 |
|  3051 |
|  3192 |
|  3761 |
|  3085 |
|  3418 |
|  3341 |
|  3066 |
|  3353 |
|  3287 |
|  3037 |
+-------+
11 rows in set (0.23 sec)

mysql>

mysql> select * from DUMMY;
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
| seqno | account_no | stock_symbol         | start_volume | start_amount  | start_price   | stock_type | trustee_id |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
|     1 | 0016100    | BANPU                | 0000045000   | 0000645569.57 | 000014.345990 | 02         |            |
+-------+------------+----------------------+--------------+---------------+---------------+------------+------------+
1 row in set (0.00 sec)

mysql>

 

mysql> select T2.t_regtime,T2.t_cnt from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2 where T2.t_cnt > 3000;
+-------------------+-------+
| t_regtime         | t_cnt |
+-------------------+-------+
| 20190828 11:19:27 |  3462 |
| 20190828 11:19:30 |  3051 |
| 20190828 11:19:38 |  3192 |
| 20190828 11:19:46 |  3761 |
| 20190828 11:19:47 |  3085 |
| 20190828 11:19:55 |  3418 |
| 20190828 11:20:00 |  3341 |
| 20190828 11:20:03 |  3066 |
| 20190828 11:20:12 |  3353 |
| 20190828 11:20:15 |  3287 |
| 20190828 11:20:20 |  3037 |
+-------------------+-------+
11 rows in set (0.19 sec)

mysql>  

 

mysql> select T2.t_regtime,T2.t_cnt from DUMMY T1, (select substr(regtime,1,17) as t_regtime, count(1) as t_cnt from RB_OCUS_POS_TEST2 group by substr(regtime,1,17)) T2 where T2.t_cnt > 3000 order by T2.t_cnt desc;
+-------------------+-------+
| t_regtime         | t_cnt |
+-------------------+-------+
| 20190828 11:19:46 |  3761 |
| 20190828 11:19:27 |  3462 |
| 20190828 11:19:55 |  3418 |
| 20190828 11:20:12 |  3353 |
| 20190828 11:20:00 |  3341 |
| 20190828 11:20:15 |  3287 |
| 20190828 11:19:38 |  3192 |
| 20190828 11:19:47 |  3085 |
| 20190828 11:20:03 |  3066 |
| 20190828 11:19:30 |  3051 |
| 20190828 11:20:20 |  3037 |
+-------------------+-------+
11 rows in set (0.00 sec)

mysql>

 

 

'데이타베이스 > MySQL' 카테고리의 다른 글

MySQL ROWNUM(select @r:=@r+1 As rowNum)  (0) 2019.10.31
TIP - SEQ증감  (0) 2019.10.31
FUNCTION 생성및 활용  (0) 2019.10.31
LINUX,프로그래밍을 통한 PROCEDURE 호출후 결과  (0) 2019.10.30
#LINUX,common.c(MySQL)  (0) 2019.10.30

 

#####FUNCTION 생성

 

DROP FUNCTION IF EXISTS GETMASTER_SYMB;

DELIMITER $$
CREATE FUNCTION GETMASTER_SYMB(intput1 TEXT, intput2 TEXT) RETURNS TEXT
BEGIN

    DECLARE p_result    TEXT;
    DECLARE p_input1    TEXT;
    DECLARE p_input2    TEXT;

 

    SET p_input1 = intput1;
    SET p_input2 = intput2;

 

    SET p_result = (SELECT  SYMB FROM fssmaster WHERE ( COD2 = p_input1 OR COD1 = p_input2 ))
    ;

    RETURN p_result;
END $$
DELIMITER ;

 

 

#####FUNCTION 활용

C:\Users\kiwoom\Downloads>
C:\Users\kiwoom\Downloads>mysql -u root -p
Enter password: ***********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.1.35-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use fss;
Database changed
mysql> SELECT fss.GETMASTER_SYMB('4262', '4263');
+------------------------------------+
| fss.GETMASTER_SYMB('4262', '4263') |
+------------------------------------+
| AAV                                |
+------------------------------------+
1 row in set (0.02 sec)

mysql>
mysql>
mysql>

 

/*

 * gcc -c sample.c

 * gcc -o sample sample.o libmysql.lib

 */

 

#include "C:\Program Files\MySQL\MySQL Connector C 6.1\include\mysql.h"
#include <string.h>
#include <stdio.h>

#define DB_HOST "127.0.0.1"
#define DB_USER "root"
#define DB_PASS "eogksalsrnr"
#define DB_NAME "fss"
    
int main(void)
{
    MYSQL *connection=NULL, conn;
    MYSQL_RES *sql_result;
    MYSQL_ROW sql_row;
    int query_stat; 
    
    mysql_init(&conn);

    connection = mysql_real_connect(&conn, DB_HOST, DB_USER, DB_PASS, DB_NAME, 3306, (char *)NULL, 0);

    if (connection == NULL)
    {
        fprintf(stderr, "Mysql connection error : %s", mysql_error(&conn));
        return 1;
    }

    query_stat = mysql_query(connection, "SELECT fss.GETMASTER_SYMB('4262', '4263')");
    if (query_stat != 0)
    {
        fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
        return 1;
    }
    
    sql_result = mysql_store_result(connection);
    
    while ( (sql_row = mysql_fetch_row(sql_result)) != NULL )
    {
        printf(">>>>>>%s\n", sql_row[0]);
    }

    mysql_free_result(sql_result);

    mysql_close(connection);

    return 0;​
}
 

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

 

#define LEAP(y) ((y % 4 == 0 && y % 100 != 0 || y % 400 == 0) ? 1 : 0)

 

static void ha_ltona0(int idx, int length, char *answer);

static int ha_antol(char *request, int length);

static void cb1_compute_date (char *odate, char *idate, int addval);

static int getRemainDay(char *odate, char *idate);

 

int main(int argc, char *argv[])

{

    int rc,mm,dd;    char begin_date[10] = "20190101";

   char end_date [10];

   for(mm=1; mm<=12; mm++)

   {

      for(dd=1; dd<=31; dd++)

      {

         memset(end_date,0x00,sizeof(end_date));

         sprintf(end_date, "2019%.2d%.2d", mm, dd);

         rc = getRemainDay(end_date,begin_date);

         if(rc<0) printf("(%s)(%s):(%s)\n", begin_date, end_date, " is not valid day!! error");

         else printf("(%s)(%s):(%d)\n", begin_date, end_date, getRemainDay(end_date,begin_date));

      }

   }

for(mm=1; mm<=12; mm++) { for(dd=1; dd<=31; dd++)

{

memset(end_date,0x00,sizeof(end_date));

sprintf(end_date, "2019%.2d%.2d", mm, dd);

rc = getRemainDay(end_date,begin_date);

if(rc<0) printf("(%s)(%s):(%s)\n", begin_date, end_date, " is not valid day!! error");

}

}

   return 0;

}

 

/*- ------------------------------------------------ -*

 *- ha_ltona0

 *- ------------------------------------------------ -*/

void ha_ltona0(int idx, int length, char *answer)

{

    if(length==1)

    {

        sprintf(answer,"%.1d",idx);

    }

    else if(length==2)

    {

        sprintf(answer,"%.2d",idx);

    }

    else if(length==3)

    {

        sprintf(answer,"%.3d",idx);

    }

    else if(length==4)

    {

        sprintf(answer,"%.4d",idx);

    }

}

 

/*- ------------------------------------------------ -*

 *- ha_antol

 *- ------------------------------------------------ -*/

int ha_antol(char *request, int length)

{

char answer[100];

 

memset(answer,0x00,sizeof(answer));

 

memcpy(answer,request,length);

 

return(atoi(answer));

}

 

/*- ------------------------------------------------ -*

 *- cb1_compute_date

 *- ------------------------------------------------ -*/

void cb1_compute_date (odate, idate, addval)

char *odate;

char *idate;

int addval;

{

int yy;

int mm;

int dd;

int leap;

static int mmt[2] [13] =

{ {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},

   {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };

 

yy = ha_antol(idate, 4);

mm = ha_antol(idate+4, 2);

dd = ha_antol(idate+6, 2) + addval;

leap = LEAP(yy);

if (addval == 0) {

sprintf(odate, "%.8s", idate);

return;

    }

else

if (addval > 0) {

     for ( ; dd > mmt[leap][mm]; mm++)

     {

     dd -= mmt[leap] [mm];

     if (mm >= 12)

     {

         mm = 0;

         yy++;

         leap = LEAP(yy);

     }

     }

}

else {

     mm--;

     if (mm == 0)

     {

     mm = 12;

     yy--;

     leap = LEAP(yy);

     }

 

     for ( ; dd < 1; mm--)

     {

     dd += mmt [leap] [mm];

     if (mm <= 1)

     {

         mm = 13;

         yy--;

         leap = LEAP(yy);

     }

     }

     mm++;

     if (mm > 12)

     {

     mm = 1;

     yy++;

     }

}

 

ha_ltona0(yy, 4, odate);

ha_ltona0(mm, 2, odate+4);

ha_ltona0(dd, 2, odate+6);

}

 

/*- ------------------------------------------------ -*

 *- getRemainDay

 *- ------------------------------------------------ -*/

int getRemainDay(char *odate, char *idate)

{

int k;

char begin_date[10];

 

if(strcmp(odate,idate)<0) return(-1);

 

if(memcmp(odate,idate,strlen("YYYYMMDD"))==0) return 1;

 

    for(k=1; k<9999; k++)

{

     memset(begin_date,0x00,sizeof(begin_date));

     cb1_compute_date(begin_date,idate,k);

 

if(memcmp(begin_date,odate,strlen("YYYYMMDD"))==0) break;

}

 

if(k==9999) return(-1);

return k+1;

}

 

/*RESULT

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Corporation. All rights reserved.

 

C:\Users\Downloads>10

,,

,,

,,

,,

(20190101)(20190818):(230)

(20190101)(20190819):(231)

(20190101)(20190820):(232)

(20190101)(20190821):(233)

(20190101)(20190822):(234)

(20190101)(20190823):(235)

(20190101)(20190824):(236)

(20190101)(20190825):(237)

(20190101)(20190826):(238)

(20190101)(20190827):(239)

(20190101)(20190828):(240)

(20190101)(20190829):(241)

(20190101)(20190830):(242)

(20190101)(20190831):(243)

(20190101)(20190901):(244)

(20190101)(20190902):(245)

(20190101)(20190903):(246)

(20190101)(20190904):(247)

(20190101)(20190905):(248)

(20190101)(20190906):(249)

(20190101)(20190907):(250)

(20190101)(20190908):(251)

(20190101)(20190909):(252)

(20190101)(20190910):(253)

(20190101)(20190911):(254)

(20190101)(20190912):(255)

(20190101)(20190913):(256)

(20190101)(20190914):(257)

(20190101)(20190915):(258)

(20190101)(20190916):(259)

(20190101)(20190917):(260)

(20190101)(20190918):(261)

(20190101)(20190919):(262)

(20190101)(20190920):(263)

(20190101)(20190921):(264)

(20190101)(20190922):(265)

(20190101)(20190923):(266)

(20190101)(20190924):(267)

(20190101)(20190925):(268)

(20190101)(20190926):(269)

(20190101)(20190927):(270)

(20190101)(20190928):(271)

(20190101)(20190929):(272)

(20190101)(20190930):(273)

(20190101)(20190931):( is not valid day!! error)

(20190101)(20191001):(274)

(20190101)(20191002):(275)

(20190101)(20191003):(276)

(20190101)(20191004):(277)

(20190101)(20191005):(278)

(20190101)(20191006):(279)

(20190101)(20191007):(280)

(20190101)(20191008):(281)

(20190101)(20191009):(282)

(20190101)(20191010):(283)

(20190101)(20191011):(284)

(20190101)(20191012):(285)

(20190101)(20191013):(286)

(20190101)(20191014):(287)

(20190101)(20191015):(288)

(20190101)(20191016):(289)

(20190101)(20191017):(290)

(20190101)(20191018):(291)

(20190101)(20191019):(292)

(20190101)(20191020):(293)

(20190101)(20191021):(294)

(20190101)(20191022):(295)

(20190101)(20191023):(296)

(20190101)(20191024):(297)

(20190101)(20191025):(298)

(20190101)(20191026):(299)

(20190101)(20191027):(300)

(20190101)(20191028):(301)

(20190101)(20191029):(302)

(20190101)(20191030):(303)

(20190101)(20191031):(304)

(20190101)(20191101):(305)

(20190101)(20191102):(306)

(20190101)(20191103):(307)

(20190101)(20191104):(308)

(20190101)(20191105):(309)

(20190101)(20191106):(310)

(20190101)(20191107):(311)

(20190101)(20191108):(312)

(20190101)(20191109):(313)

(20190101)(20191110):(314)

(20190101)(20191111):(315)

(20190101)(20191112):(316)

(20190101)(20191113):(317)

(20190101)(20191114):(318)

(20190101)(20191115):(319)

(20190101)(20191116):(320)

(20190101)(20191117):(321)

(20190101)(20191118):(322)

(20190101)(20191119):(323)

(20190101)(20191120):(324)

(20190101)(20191121):(325)

(20190101)(20191122):(326)

(20190101)(20191123):(327)

(20190101)(20191124):(328)

(20190101)(20191125):(329)

(20190101)(20191126):(330)

(20190101)(20191127):(331)

(20190101)(20191128):(332)

(20190101)(20191129):(333)

(20190101)(20191130):(334)

(20190101)(20191131):( is not valid day!! error)

(20190101)(20191201):(335)

(20190101)(20191202):(336)

(20190101)(20191203):(337)

(20190101)(20191204):(338)

(20190101)(20191205):(339)

(20190101)(20191206):(340)

(20190101)(20191207):(341)

(20190101)(20191208):(342)

(20190101)(20191209):(343)

(20190101)(20191210):(344)

(20190101)(20191211):(345)

(20190101)(20191212):(346)

(20190101)(20191213):(347)

(20190101)(20191214):(348)

(20190101)(20191215):(349)

(20190101)(20191216):(350)

(20190101)(20191217):(351)

(20190101)(20191218):(352)

(20190101)(20191219):(353)

(20190101)(20191220):(354)

(20190101)(20191221):(355)

(20190101)(20191222):(356)

(20190101)(20191223):(357)

(20190101)(20191224):(358)

(20190101)(20191225):(359)

(20190101)(20191226):(360)

(20190101)(20191227):(361)

(20190101)(20191228):(362)

(20190101)(20191229):(363)

(20190101)(20191230):(364)

(20190101)(20191231):(365)

(20190101)(20190229):( is not valid day!! error)

(20190101)(20190230):( is not valid day!! error)

(20190101)(20190231):( is not valid day!! error)

(20190101)(20190431):( is not valid day!! error)

(20190101)(20190631):( is not valid day!! error)

(20190101)(20190931):( is not valid day!! error)

(20190101)(20191131):( is not valid day!! error)

*/

 

#include <stdio.h>

 

#if(1)

#pragma pack(1)

struct PacketHeader {

    char flags;    // 1 BYTE

    int seq;       // 4 BYTE

};

#pragma pack()

#endif

 

#if(0)

struct PacketHeader {

    char flags;    // 1 BYTE

    int seq;       // 4 BYTE

} __attribute__((aligned(1), packed));

#endif

 

#if(0)

struct PacketHeader {

    char flags;    // 1 BYTE

    int seq;       // 4 BYTE

};

#endif

 

int main()

{

    struct PacketHeader header;

 

    printf("%d\n", sizeof(header.flags));

    printf("%d\n", sizeof(header.seq));  

    printf("%d\n", sizeof(header));      

 

    return 0;

}

 

//정상적인 경우는 1+4=8바이트의 크기로 구조체크기가 결정되지만

//#pragma pack(1)를 사용함으로써 구조체 정렬 크기조정할수 있다.

 

 

#include <stdio.h>

 

int main(void)

{

    printf("%.2f\n\n", 0.25676);

    return 0;

}

 

/*

결과:0.26

*/

'c 언어 > 초급과정' 카테고리의 다른 글

중복되지않는 문자출력  (0) 2020.08.26
printf () 함수 활용  (0) 2019.10.31
[C언어] Header File 한번만 포함하기.  (0) 2019.10.31
WINDOWS, 키보드 주므르기(102)  (0) 2019.10.31
WINDOWS, 키보드 주므르기(101)  (0) 2019.10.31

C언어로 프로그래밍을 하다보면 하나의 헤더파일이 여러 곳에서 참조될 때가 있다.

컴파일 시 해당 헤더파일이 여러번 중복되서 참조되는 상황을 막기 위해

 

#ifndef 와 #define이 사용된다.

 

예를 들어 test.h라는 헤더파일이 있다고 하자.

 

헤더파일의 가장 위에

 

#ifndef __TEST_H__

#define __TEST_H__

 

// 내용 작성

#define MAX_LEVEL 999

 

#endif

 

위와 같이 작성하게 되면 __TEST_H__이 상수화 되어 헤더파일 참조 시 해당 파일 참조되었으므로 

한번만 참조하게 된다.

 

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

#변수가 아닌이상, 여러번 참조해도 괜찮지만, 코드의 가독성및 사이즈에 영향을 미치게 된다.

 

 

 

 

+ Recent posts