학교 프로젝트 주제로 네트워크 패킷캡쳐 프로그램을 구현하기 winpcap에 대해 알아 보게 됐다!
.
.
.
일단 WinPcap란 무엇인가....!?
www.winpcap.org <- 여기에 가보면 잘 설명이 되어있다 영어로...
일반적으로 네트웍카드에는 항상 패킷이 오고가고 있다! 하지만 그걸 NIC(network interface card)에서는 들어오는 패킷이 나에게 오는것이 맞는가를 확인하고 맞다면 받아들여서 그에맞는 application으로 보내주고, 아니라면 즉각 폐기해 버린다.

사용자 삽입 이미지

대략 이런 구조로 되어있어서 폐기되기전에 읽어들여 버리면 자신의 컴퓨터에 NIC를 거치는 패킷을 볼 수 있다는 것이다. 하지만 물론 패킷들이 암호화 되어있고 또한 패킷의 헤더와 기타 불필요한 정보들이 덧붙어 있기 때문에 분석하기는 어렵다. 그리고 window환경에서는 application층에서 NIC에 직접적인 접근이 불가하다. 완전히 방법이 없는것은 아니다. fillter-driver를 이용한다든지 우회적인 방법이 있다.
여기서 Winpcap는 fillter-driver역활을 하는것이다.
원래는 linux에는 libpcap가 있다.
.
Winpcap작업 환경을 구축하려면 일단 위에 링크된 사이트에 접속하여 왼쪽에 보이는 메뉴에서 Development로 가서 WinPcap Developer's Pack을 다운로드하여 적당한곳에 압축을 푼다. 그리고 visual studio 환경이라면 도구 -> 옵션에서 프로젝트 솔루션 항목을 선택 하위항목인 VC++프로젝트에서 참조파일에 lib폴더를 포함시켜주고, 포함파일에 include폴더를 포함시켜준다. 그리고 dll파일을 필요로 하는데 링크된 사이트에서 winpcap를 받아서 인스톨해준다.
그럼 이상으로 winpcap를 이용할 환경은 구축 되었다!

Posted by hazeyun
,

3인칭 시점의 게임은 카메라가 캐릭터의 일정거리 뒤쪽에 위치하게 됩니다.
거기에 지형을 통메쉬로 만들어 상하좌우가 막혀있는 공간이다 보니 캐릭이 벽에 가까이 다가서게 되면
카메라가 지형밖으로 나가 버리게 되고 캐릭은 지형에 가려서 보이지 않게 됩니다.
처음 생각한 방법이 간단하게 지형 메쉬를 렌더 할 때 D3DRS_CULLMODE를  D3DCULL_NONE으로 해서
카메라가 지형 밖에 위치하게 되면 벽면을 그려주지 않게 하는 방법입니다.  
하지만 이방법은 너무 허접해 보여서 탈락.
그래서 일반적인 방법을 이리저리 찾아봤는데 projection의 nearplane을 지형과 어찌 저찌 해야
한다는 방법이었는데 찬찬히 읽어보다가 갑자기 생각난 것으로 일단 땜방했습니다.
.
.
본론으로가서 이용한 방법은 D3DXIntersect함수를 사용해서 체크하는 방법입니다.
D3DXIntersect함수가 부하가 많이 걸린다는 말을 어디서 본것 같은데 어디까지나 임시 방편이기
때문에 그부분은 스킵.
일단 이론은 카메라에서 캐릭방향으로 ray를 쏴서(카메라가 캐릭을 바라보고있기 때문)
쏘아진 ray에 지형 메쉬의 충돌이 있는가 확인해서 카메라가 밀려난 만큼 보정을 해주는 방법입니다.

구현의 요점은
//카메라의 시점벡터...matView는 viewtransformMatirx...
D3DXVECTOR3 dir(matView._13, matView._23, matView._33); 

//시점벡터를 정규화 해줌....
D3DXVec3Normalize(&dir, &dir);  

//정규화 해준 dir과 지형메쉬인 포인터인 g_pCollMesh, 카메라의 좌표인 vEyept를 넣어줘서
//intersect함수를 통해서 지형메쉬와의 충돌을 체크해줌....
//여기서 카메라의 좌표는 최종 월드변환후의 좌표...
D3DXIntersect(g_pCollMesh, &vEyept, &dir, &bHit, &dNearIndex, &u, &v, &dist, &pBuffer, &dCount);  

반환해주는 bHit를 통해서 메쉬와의 충돌유무를 확인 할 수 있습니다.
충돌 되었다는것은 결국 카메라가 바라보는 시점에 메쉬가 위치한다는 것입니다.
하지만 여기서 생각해 봐야 될께 바닥면과의 충돌일 수도 있기 때문입니다.

그래서 마지막으로
//캐릭터 좌표벡터에서 카메라 좌표벡터를 빼서 거리를 구함....
float fRadius = D3DXVec3Length(&(vCharPos - vEyept));  

여기서 구한 캐릭과 카메라의 거리사이에 충돌지점이 있는지 확인 해야 됩니다.
그부분이 intersect함수에서 반환해주는 dist를 통해서  확인 가능합니다.
if(dist < fRadius)
{
    //지형과 ray의 충돌지점이 카메라와 캐릭사이에 있을경우 진입.....
}
하지만 이방법의 경우 땜빵 방법이라 더 알아 봐야겠습니다.
어디까지나 임시방편;;ㅋ

Posted by hazeyun
,

[연습문제] - 1.20

Study/SICP 2008. 4. 1. 23:49

문제)프로시저가 만들어 내는 프로세스는 마땅히 실행기의 계산 규칙에서 영향을 받는다. 앞서 나온 gcd프로시저를 보기 삼아서, 이런 문제를 살펴보자. 먼저 이번에는 (1.1.5절에서 선보인) normal-order evaluation을 따른다고 하자. (if를 normal-order evaluation방법은 연습문제 1.5에 있다.) substitution으로 (gcd 206 40)를 (normal-order)구하는 프로세스를 보이고, remainder 연산을 어디에서 쓰는지 표시하자. 프로세스가 끝날 때까지 remainder 연산을 얼마나 쓰는가? applicative-order evaluation하는 경우라면 또 어떠한가?


풀이)

normal-order로 구하는 프로세스는 따로 정의 할 필요 없을듯 해서 앞에서 나온 gcd프로시저를 그대로 사용

(define (gcd a b)

      (if (= b 0) a (gcd b (remainder a b))))

(remainder a b) 는 a를b로 나눈 수의 나머지를 취하는 프로시저다.. c언어에서의 %연산이라 생각하면됨.


normal-order evaluation 일때 remainder연산의 사용횟수 = 'rmd' 라 두고!!

(gcd 206 40)

    (if (= 40 0)  206  (gcd 40 (remainder 206 40)))       40 = 0 아니므로 뒤의 결과를 취함 rmd = 0

-> (gcd 40 (remainder 206 40)                                                                               rmd = 0

-> (if (= (remainder 206 40) 0)

        40

        (gcd (remainder 206 40) (remainder 40 (remainder 206 40))))                          rmd = 0

-> (if (= 6 0)

        40

        (gcd (remainder 206 40) (remainder 40 (remainder 206 40))))                          rmd = 1

-> (gcd (remainder 206 40) (remainder 40 (remainder 206 40)))                                rmd = 1

-> (if (= (remainder 40 (remainder 206 40)) 0)

        (remainder 206 40)

        (gcd (remainder 40 (remainder 206 40))

                (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))         rmd = 1

-> (if (= 4 0)

         (remainder 206 40)

        (gcd (remainder 40 (remainder 206 40))

                (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))         rmd = 3

-> (gcd (remainder 40 (remainder 206 40))

                (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))          rmd = 3

-> (if (= (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) 0)

        (remainder 40 (remainder 206 40))

        (gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

                (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))

                                                                                                                           rmd = 3

-> (if (= 2 0)

          (remainder 40 (remainder 206 40))

        (gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

                (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))

                                                                                                                           rmd = 7

-> (gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

           (remainder (remainder 40 (remainder 206 40))

                            (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))

                                                                                                                           rmd = 7

-> (if (= (remainder (remainder 40 (remainder 206 40))

                            (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 0)

         (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

         (gcd (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))

                 (remainder (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

                                 (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))

                                                                                                                           rmd = 7

-> (if (= 0 0)

        (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

         (gcd (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))

                 (remainder (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))

                                 (remainder (remainder 40 (remainder 206 40))

                                 (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))))

                                                                                                                           rmd = 14

-> (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))                       rmd = 14

-> 2                                                                                                                      rmd = 18

normal-order evaluation 하는 경우에는

프로세스가 끝날때 까지 사용한 remainder연산은 18번 이다.



applicative-order evaluation 일때 .... 마찬가지로 remainder연산을 rmd로 두고....

(gcd 206 40)

-> (if (= 40 0)

         206

         (gcd 40 (remainder 206 40))                                                                          rmd = 0

-> (gcd 40 (remainder 206 40))                                                                               rmd = 0

-> (gcd 40 6)                                                                                                         rmd = 1

-> (if (= 6 0)

        40

        (gcd 6 (remainder 40 6)))                                                                               rmd = 1

-> (gcd 6 (remainder 40 6))                                                                                    rmd = 1

-> (gcd 6 4)                                                                                                           rmd = 2

-> (if (= 4 0)

         6

         (gcd 4 (remainder 6 4)))                                                                                rmd = 2

-> (gcd 4 (remainder 6 4))                                                                                       rmd = 2

-> (gcd 4 2)                                                                                                           rmd = 3

-> (if (= 2 0)

         4

         (gcd 2 (remainder 4 2)))                                                                                 rmd = 3

-> (gcd 2 (remainder 4 2))                                                                                       rmd = 3

-> (gcd 2 0)                                                                                                            rmd = 4

-> (if (= 0 0)

         2

         (gcd 0 (remainder 2 0)))                                                                                 rmd = 4

-> 2

applicative-order evaluation 하는 경우에는

프로세스가 끝날때 까지 사용한 remainder 연산은 4번이다.

Posted by hazeyun
,

저번 스터디 모임때 화두가 됐던 문제입니다.

할일도 없고 잼있을거 같아서 겸사겸사 풀어봤는데요;;ㅋ

.

.

문제) 세개의 수를 입력받아서 그중에 두개의 큰수를 찾아서 그 두수의 제곱의 합을 구하는 프로시저를

작성하라..(대략 이런듯ㅋ)


풀이)  

(define (big x y)
  (if (< x y)
      y
      x))
(define (square x) (* x x))

(define (sum-of-square x y)
  (+ (square x) (square y)))

(define (check x y z)
  (if (< x y)
      (sum-of-square y (big x z))
      (sum-of-square x (big y z))))


저나름의 풀이는

일단 기존의 제곱함수인 square와 제곱의 합을 구하는 sum-of-square를 정의해주고 추가로 두 수를 입력

받아서 큰수를 찾아주는 big이라는(작명센스꽝ㅠ.ㅠ) 함수를 정의 해줬습니다. 

그리고 최종적으로 check라는 프로시저를 작성 했습니다.

.

.

이보다 더나은 해법도 물론 많겠지만 저의 머리로는....ㅋ

Posted by hazeyun
,