본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형]이상만_10월 20일(bitmap project / socket 2Way handshake)

by 알 수 없는 사용자 2011. 10. 21.
728x90
반응형
수업이 없고 프로젝트 진행이라 프로젝터 정리한 부분만큼 올렸습니다!~!!

Bitmap Project


.Bitmap의 구조
 FILE HEADER : 파일에 대한 정보를 저장
 INFORMATION HEADER : 실제 비트맵의 세부 정보 저장
 PALETTL : 각 빅셀이 가지고 있는 RGB값을 저장
                 색상이 256이하일 경우에만 해당
 DATA : 각 픽셀의 색상값 저장

한가지 색으로만 되어 있는 비트맵을 헥사뷰로 출력하였습니다>>

위 그림의 정보를 토대로 분석하도록 하겠습니다

.Bitmap의 구조
1. FILEHEADER 구조체 - 헤더에 속하며 3가지의 정보를 가지고 있습니다 정보는 아래와 같습니다

typedef struct tagBITMAPFILEHEADER
{
          WORD               bfType;                  // "BM" 이라는 값을 저장함
          DWORD             bfSize;                   // 바이트 단위로 전체파일 크기
          WORD               bfReserved1;          // 예약된 변수
          WORD               bfReserved2;          // 예약된 변수
          DWORD             bfOffBits;                // 영상데이터 위치까지의 거리
} BITMAPFILEHEADER;

오픈한 파일이 비트맵 파일인지를 가리키는 것이 bfType입니다  "BM" 문자가 있다면 Bitmap입니다.
bfOffBits 는 파일 시작부분에서 실제 데이터가 존재하는 위치까지 바이트 단위의 거리를 나타내며. 오프셋 (offset) 이라고 합니다.

참고>> 
WORD 는 2바이트 (unsigned short), DWORD 는 4 바이트 (unsigned long) 
 

2. INFOHEADER - bmp의 상세한 정보를 가지고 있고 그내요은 아래와 같습니다

typedef struct tagBITMAPINFOHEADER
{
          DWORD              biSize;                       // 이 구조체의 크기 
          LONG                biWidth;                      // 픽셀단위로 영상의 폭
          LONG                biHeight;                     // 영상의 높이
          WORD                biplanes;                    // 비트 플레인 수 (항상 1)
          WORD                biBitCount;                 // 픽셀당 비트수 (컬러, 흑백 구별)
          DWORD              biCompression;          // 압축유무
          DWORD              biSizeImage;              // 영상의 크기 (바이트 단위)
          LONG                biXPelsPerMeter;        // 가로 해상도
          LONG                biYPelsPerMeter;        // 세로 해상도
          DWORD              biClrUsed;                 // 실제 사용 색상 수
          DWORD              biClrImportant;            // 중요한 색상 인덱스
} BITMAPINFOHEADER;

3. 팔레트 구조체  - 잘 사용되지 않습니다 내용은 아래와 같습니다 
typedef struct tagRGBQUAD
{
           BYTE          rgbBlue;                  // B 성분 (파란색)
           BYTE          rgbGreen;                // G 성분 (녹색)
           BYTE          rgbRed;                   // R 성분 (빨간색)
           BYTE          rgbReserved1;          // 예약된 변수
} RGBQUAD;

 팔레트는 인덱스에 의한 컬러값을 저장하기 위한 구조체이다. 이 구조체를 사용하여 팔레트의 수 만큼 배열을 할당하여 저장한다. 256 컬러모드의 영상은 팔레트배열 크기가 256 개, 16 비트 컬러 영상은 팔레트 크기가 2^16 개이다. biClrUsed 변수를 참조하면 된다. 흑백영상의 경우 팔레트는 256 개이며, 트루컬러의 경우는 인덱스 저장이 아니라 데이터값을 직접 저장하므로 팔레트가 없다.

.구조체 정보 출력
위의 구조체 정보는 bitmap의 파일에 형성하는데 있어서 중요한 정보들을 지니고 있습니다 이러한 정보들을 정해진 위치에서 불러들인 파일에 따라 그 값만 변화됩니다 불러들인 정보를 가지고 실제로 비트맵을 화면에 나타내는데에도 사용하고 어떻게 구성되어있는지에 대한 정보도 확인 할 수 있습니다

오프셋 : 위 구조체를 바탕으로 위치를 정리하였습니다


예제>magic number(signature)를 출력하기
1) 파일을 생성합니다
 hFile=CreateFile(Sub,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);   

2)edit컨트롤을 사용하여 값이 들어갈곳을 만들어 줍니다
hEdit = CreateWindow(TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_CENTER, 750, 105, 110, 25, hWnd,(HMENU)ID_EDIT,g_hInst,NULL);  

3)원하는 위치를 wsprintf를 이용하여 입력하고  SetWindowText를 이용하여 출력합니다
ReadFile(hFile,buf,BSIZE,&dwRead,NULL);
 wsprintf(tt, TEXT(" %c%c"),buf[0],buf[1]);
 SetWindowText(hEdit,tt);

결과보기>>추가로 file size 가로 세로 폭을 출력하였습니다

참고>>가로출력
 wsprintf(tt,TEXT("%d "),*(int *)(&buf[22])) ;
 SetWindowText(hEdit3,tt);

.API 전체적 흐름
: 프로그램을 제작하기전에 어떻게 구현해 나갈것인가 미리 구상을 해보았습니다 단순히 기본문에서 소스들을 추가해나가니 소스가 깔끔하지 못하고 복잡해지며 정리가 잘되지 않았습니다 그리고 에러 발생시 처리를 해야될 상황에서 곤란하여 기본형에서 시작하되 원하는 기능과 관련 소스들을 정리하여 만들어 나가는 것이 가장 좋은 방법이 아닐까 생각이되어 그려보게 되었습니다

전체적인 흐름>>

1) Create : 창을 생성하고 초기 값을 세팅하여 미리 지정해둔 비트맵을 화면에 뿌려줍니다

2) 버튼 컨트롤
   WM_KEYDOWN : 버튼을 눌력 상하로 스크롤이 가능 합니다
   WM_MOUSEWHEEL : 스크롤시 마우스 휠을 가능하도록 하였습니다
   WM_VSCROLL : 그림이 화면 밖으로 나가게 되면 스크롤을 하여 화면 밖의 이미지를 볼수 있도록 합니다

3)PAINT : 비트맵을 계산하여 화면에 뿌려줍니다 여기서 2가지 파트로 나누었습니다
Paint : hMemDC를 가지고 BitBlt를 이용하여 고속복사를 수행합니다 고속복사를 사용하지 않게 되면 화면 에 그림이 떠지는 속도가 상당히 느려집니다
void BitmapDraw(hWnd) : 비트맵의 정보를 뿌려주는 역활과 데이터를 계산하여 hMemDC에 넣어주는 역활을 합니다 이렇게 따로 함수 처리를 해준 이유는 open을 눌러 비트맵을 선택했을때나 초기 시작화면 기타 처리 상황이 발생 했을 경우에 그림을 표시하기 위해서 만들었습니다

4)COMMAND : radio와 Menu.rc를 처리하고 BitmapDraw() switch에 들어온 명령에 따라 호출됩니다

결과보기>>
    1)기본 출력화면입니다

    2)90도 회전한 화면입니다

   3)180도 회전한 화면입니다

4)270도 회전한 화면입니다

   5)흑백처리한 화면입니다


Soket 3Way Handshake

.3Way Handshake
TCP 3 Way Handshake는 TCP/IP프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미합니다.이 과정에서 송신측과 수신측에 총 3개의 패킷이 생성이 되기 때문입니다

참고>>3way 4way? 뭐가 다른가?
예를 들어 악수를 합니다
3way의 경우 "악수합시다" 상대방에게 요청을 하여 "그래요 합시다"하여 의사를 결정후 손을 내밀어서 악수의 준비를 완료가 되면 악수가 이루어지는 방식이라고 볼 수 있습니다
4way의 경우 "악수합시다" 상대방에게 요청을 하면 "저말씀입니까?" "정말로 저와 하시겠습니까?" 의사를 제차 확인한 후에 상대방이 "그래요 합시다"하고 손을 내밀어서 악수의 준비가 완료되면 악수가 이루어지는 방식입니다

.목표
TCP통신에서 socket으로 생성된 두 프로그램이 일련의 과정을 거쳐서 메세지를 주고 받고 종료될때까지 패킷의 내용을 분석하여 의미를 파악하는 것입니다

.준비단계 - test를 위해 3가지의 파일이 필요합니다
소켓설정은 socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) ;으로 동일합니다

1)client.c 
   socket() ->  connect() ->  메세지 수송신

2)server.c
   socket() ->   bind() ->  listen() -> accept() ->   메세지 수송신

3)packet analyzer.c 
   1계층 ethetnet -> 2계층 IP -> 3계층 TCP
   * 20회 정도를 실행하도록 for문을 걸었습니다
   * 1,2계층의 정보는 출력하지 않습니다 

참고>>고정 아이피 사용?
TCP를 테스트하기 위해서 내부 아이피주소(127.0.0.1)을 사용하면 패킷이 잡히지가 않습니다 그래서 고정아이피로 세팅해주고 자신의 컴퓨터에서 client server를 실행하면 않되고 2대의 서로 다른 컴퓨터에서 테스트를 해야 정상적으로 출력이 됩니다

.실행
server를 실행한후 packet과 client를 실행 하였습니다
15번 실행되면 TCP정보가 아래 그림과 같이 나타났습니다

./server

 

./packet analyzer



.패킷분석표 - 프로그램을 실행하여 나온 20개의 데이터 값을 정리하여 표로 만들었습니다

순서

Source

Destination

Seq Num

Ack Num

Fin

Syn

Ack

1

1682

49152

1100612098

1155894860

0

0

1

2

2169

3000

1306455164

0

0

1

0

3

3000

2169

1306455165

1036455165

0

1

1

4

3697

2869

1156146258

0

0

1

0

5

2869

3697

2068327811

115614259

0

1

1

6

2169

3000

1306455165

1307210305

0

0

1

7

2169

3000

1306455165

1307210305

0

0

1/psh

8

3000

2169

1307210305

1306455170

0

0

1/psh

9

3697

2869

1156146259

02068327812

0

0

1

10

3000

2169

1307210305

1306455170

0

0

1

11

3000

2169

1307210310

1306455170

1

0

1

12

2169

3000

1306455170

1307210310

0

0

1

13

3697

2169

1156146259

2068327812

0

0

1

14

2169

3000

1306455170

1307210311

1

0

1

15

3000

2169

1307210311

1306455171

0

0

1

 

참고>>
실행하던 시점(client 3000)의 server에서 다른 컴퓨처와 연결된 client(3697)가 있어서 표에서는 2가지의 값을 나타나고 있습니다

 

참고>>flag
SYN(Synchronization)
세션을 설정하는 데에 사용되며 초기에 시퀀스 번호를 보내게 된다. 시퀀스 번호는 임의적으로 생성하여 보낸다.

ACK(Acknowledgement)
받는 사람이 보낸 사람 시퀀스 번호에 TCP 계층에서 길이 또는 데이터 양을 더한 것과 같은 ACK를 보냅니다. ACK의 번호와 응답을 통해 보낸 패킷에 대한 손실을 판단하여 재전송 하거나 다음 패킷을 전송한다.

FIN(Finish)     
세션을 종료시키는 데에 사용되며 보낸 사람이 더이상 보낸 데이터가 없음을 보여준다.

RST(Reset)
재설정(Reset)을 하는 과정이며 양방향에서 동시에 일어나는 중단 작업이다. 비 정상적인 세션 연결 끊기에 해당한다.

PSH(Push)
대화형 트랙픽에 사용되는 것으로 버퍼가 채워지기를 기다리지 않고 데이터를 전달한다. 데이터는 버퍼링 없이 바로 위 Layer가 아닌 7 Layer의 응용프로그램으로 바로 전달한다.

.Handshake의 단계
1) 연결요청 단계 - 3way handshake



위의 패킷분석표에서 2,3,6에 해당합니다

2

2169

3000

1306455164

0

0

1

0

3

3000

2169

1306455165

1036455165

0

1

1


2 번에서는 비어있던 3000포트 향해서 채워지고 syn이1 이되었습니다
 여기는 "저와 악수를 하겠습니까"에 해당합니다

3 번에서는 3000포트에서 부터 syn1 ack1을 보냅니다
 여기는 "그래요 합시다"에 해당합니다

6

2169

3000

1306455165

1307210305

0

0

1


6번에서는 3000포트를 향해서 ack1을 다시 보냅니다
 손을 내밀며 연결 요청이 되었음을 가리킵니다 

2) 연결종료 단계 - 4way handshake


위의 패킷분석표에서 11,12,14,15에 해당합니다

11

3000

2169

1307210310

1306455170

1

0

1

12

2169

3000

1306455170

1307210310

0

0

1

11번에서 fin 1 ack 1을 보내어 종료를 하겠다는 의사를 밝힙니다
12번에서 일단 1번 생각하고

14

2169

3000

1306455170

1307210311

1

0

1

15

3000

2169

1307210311

1306455171

0

0

1

14번에서 fin 1 ack 1을 보내서 확실한 결정을 내립니다
15번에서 종료메세지 처리를 완료하게됩니다

문제점>>ack 카운트
11 12번의 데이터를 보면 akc가 카운트 되지 않고 있습니다 분석해본 결과로는 fin 으로 받은 다음 2번을 보낸 후에 최종결과를 보내기 때문에 받아 들이는 입장에서는 14번이 되어야지만 데이터를 처리 할 수 있습니다 그래서 14번부터 ack 가num에 카운트 됩니다 

참고>>데이터 전달 psh

7

2169

3000

1306455165

1307210305

0

0

1/psh

8

3000

2169

1307210305

1306455170

0

0

1/psh


7번과 8번에서는 psh(push)가 1세팅되었습니다 이것은 상위 응용프로그램 단계에 데이터가 쓰여졌다는 의미입니다 즉 read write로 데이터를 주고 받았다는 것을 알수 있습니다

728x90