2013년 8월 14일 수요일

[Network Programming] 수신가능, 송신불가 상태

네트워크 단에서 규칙설정을 하지 않고서야,

서버프로그램이 수신데이터만 받고, 송신데이터는 전송하지 못하는 현상이 발생할 것이라 생각하지 못했다.

현상을 정리하면 다음과 같다.

- 메모리 점유율 95%의 Windows 서버 ( svchost.exe에 의한 버그인 것으로 추정 )
- 1개의 서버 프로그램
- 수백개의 외부클라이언트
- 클라이언트의 접속 및 송신데이터는 서버에서 정상처리
- 서버의 응답데이터는 로그 상 정상전송으로 기록
- 반면, 클라이언트는 응답데이터를 받지 못함. ( wireshark에서도 감지하지 못함 )


서버프로그램의 수정은 2주 전에 이루어졌고,

현상은  0시 기준으로 발생하여, 네트워크 야간작업에 실수가 있었을 것이라 예상하였으나

실제로는 서버프로그램의 문제로 밝혀졌다.

몇 개월 전 코드로부터 수정사항을 하나씩 적용하면서 현상 재발생을 기다렸으나,

신기하게도 최신 코드를 적용할 때 까지 현상이 재발생하지 않았다.

잠재적인 리스크가 남아있어 기분이 매우 불편하지만, 다른방법으로 데이터를 보완할 수 있으므로 좀 더 시간을 두고 지켜보아야겠다.
전체적인 검토가 제일 바람직하겠지만, 시간이 여의치 않다.


결론은, 
AP를 절대적으로 신뢰해서는 안된다는 것.
수신가능, 송신불가 상태를 네트워크만의 문제로 속단하여서는 안된다는 것.

2013년 8월 12일 월요일

Project Euler : Problem.1

Q.
10보다 작은 자연수 중에서 3 또는 5의 배수는 3, 5, 6, 9 이고, 이것을 모두 더하면 23입니다.
1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면 얼마일까요?

A.
3의 배수의 합과 5의 배수의 합에서 최소공배수의 합을 뺀다.
#include 

int main()
{
 int a = 3, b = 5, max = 1000;
 int sum3=0, sum5=0, cross=0;
 int i, j, k;
 for( i = 1; a * i < 1000; i ++ ) {
  sum3+=a*i;
 }
 for( j = 1; b * j < 1000; j ++ ) {
  sum5+=b*j;
 }
 for( k = 1; a * b * k < 1000; k ++ ) {
  cross+= a*b*k;
 }
 printf("%d\n", sum3+sum5-cross);
 return 0;
}
그냥 단순하게 하면 이처럼 해도 되지만, 1~n까지의 합을 다음과 같이 구하는 것이 조금 더 효율적이다.
단, 최소공배수인 15는 이미 알고있다고 가정한다.

 1~n까지 연속된 수의 합은 n * ( n+1 ) / 2 이므로, 각 배수의 합은 여기에 해당 값을 곱하면 된다.
#include 

int main()
{
  int Cnt3 = 0, Cnt5 = 0, Cnt15 = 0;
  int sum3 = 0, sum5 = 0, sum15 = 0;
  int max = 1000;

  Cnt3 = max / 3;
  Cnt5 = max / 5;
  Cnt15= max / 15;

  sum3 = ( Cnt3 * ( Cnt3 + 1 ) / 2 ) * 3;
  sum5 = ( Cnt5 * ( Cnt5 + 1 ) / 2 ) * 5;
  sum15 = ( Cnt15 * ( Cnt15 + 1 ) / 2 ) * 15;

  printf("%d\n", sum3 + sum5 - sum15);
  return 0;
}

위를 일반화 시키면 다음과 같다.
프로그램 실행 시, 해당하는 인자값을 받도록 수정하였다.
사용 : 실행파일 [인자1] [인자2] [제한값]

#include <stdio.h>

int getLCM(int left, int right);     // 최대공약수를 반환하는 함수
int getGCD(int left, int right);     // 최소공배수를 반환하는 함수
int getCntInRange(int num, int range); // 범위내 인자의 배수 갯수를 반환하는 함수
int getSumInRange(int num, int range); // 범위내 인자의 배수 합을 반환하는 함수

int main(int argc, char* argv[] )
{
  int paramCnt = argc;
  if( argc != 4 ) 
  { 
    printf("사용법 : [실행파일명] [첫번째수] [두번째수] [제한값]\n");
    return -1;
  }

  int lcm = 0;
  int left = atoi(argv[1]);          // 문자열 인수를 숫자로 변환
  int right = atoi(argv[2]);
  int max = atoi(argv[3]);

  lcm = getLCM( left, right );
  
  printf("%d\n", getSumInRange( left, max )
                  - getSumInRange( right, max )
                  - getSumInRange( lcm , max ) );
  return 0;
}

int getLCM(int left, int right)
{
  return left*right/getGCD(left,right);  // 두 인자의 곱에서 최대공약수로 나누면, 최소공배수가 나온다.
}

int getGCD(int left, int right)
{
  int temp = 0;                 // 유클리드 호제법에 의해 최대공약수를 구한다.
  while(right)
  {
    temp = left % right;
    left = right;
    right = temp;
  }
  return left;
}

int getSumInRange(int num, int range)
{
  int cnt = getCntInRange(num, range);
  return cnt * ( cnt + 1 ) / 2 * num;    // n까지의 자연수 합에 인자값을 곱하여, 범위 내 인자값의 배수 합을 구한다.
}

int getCntInRange(int num, int range)
{
  return range / num;
}