반응형

11-1. 프로세스간 통신(Inter-Process Communication)

프로세스간 통신의 정의

독립된 프로세스 간에 데이터를 주고 받는 행위를 의미

프로세스간 통신의 문제점

독립된 프로세스는 (특정 시스템콜을 하지 않는한) 공유 메모리가 존재하지 않기 때문에 데이터를 주고 받는 것이 불가능.

해결책 : 독립된 프로세스들이 통신할 수 있도록 '파이프'를 제공.


파이프 생성함수

#include <unistd.h>

int pipe(int fd[2]);

파이프는 커널 객체이다. fd[1]은 파이프 입구, fd[0]은 파이프 출구로 사용한다.

리턴 : 성공시 0, 실패시 -1

파이프의 생성과 프로세스간 통신


파이프의 특징

1. 파이프는 fork 함수에 의해서 복사되지 않는다.

-> 파이프의 입출력을 의미하는 파일 디스크립터가 복사되는 것.

2. 파이프는 방향성이 존재하지 않는다.

-> 파이프의 입구와 출구만 있다. (자신이 쓰고 읽을 수 있는 문제 발생 가능)


양방향 통신을 위한 파이프의 생성

하나의 파이프는 하나의 용도로만 사용한다.

예시) A->B 파이프, B->A 파이프


11-2. 가위 바위 보 게임 구현하기

가위 바위 보 게임 구조

1단계 : 파이프 생성

2단계 : 자식 프로세스 생성

3단계 : (서버, 클라이언트 모두) 데이터 입력(가위 바위 보 선택)

4단계 : 파이프를 통해 데이터 전송(자식->부모)

5단계 : 승자 확인!

6단계 : 결과 전송(부모->자식)

반응형
반응형

10-1 다중 접속 서버의 구현 방법들

※ 클라이언트의 (여러명)다중 접속을 허용(concurrent server).

리눅스 기반의 다중 접속 서버 구현 방법들

1. 프로세스 생성을 통한 멀티태스킹(Multitasking) 서버의 구현

2. select 함수에 의한 멀티플렉싱(Multiplexing) 서버의 구현

3. 쓰레드 기반으로 하는 멀티쓰레딩(Multithreading) 서버의 구현


10-2. 프로세스의 생성

프로세스에 대한 이해

1. 실행되고 있는 프로그램의 기본 단위

2. 생성된 프로세스는 운영체제에 의해 할당된 고유한 ID를 가진다.

3. 하나의 프로그램 내에서 여러 개의 프로세스가 동시에 실행 될 수 있다.


ps -u : 어떤 프로세스가 수행되고 있는 지 보여준다. (shell 명령)

pid : 프로세스 아이디


fork 함수 호출을 통한 프로세스 생성


#include<sys/types.h>

#include<unistd.h>


pid_t fork(void);

성공시 프로세스 ID(자식프로세스면 0), 실패시 -1


프로세스 생성 예제

소스내용

a=10;

(... 중략 ...)

pid = fork();

// fork()를 호출하자마자 메모리 상태.

(... 중략...)

printf("fork 성공, 프로세스 id : %d\n",pid);

if(pid==0)

    data +=10;

else

    data -=10;

printf("data : %d",pid);

(...중략...)


10-3 프로세스&좀비(Zombie) 프로세스

좀비 프로세스 : 프로세스 종료후 메모리 상에서 사라지지 않는 프로세스

첫번째 그림

자식 프로세스는 부모 프로세스가 (종료)리턴 값을 받을 때까지 메모리 상에서 사라지지 않는다.

(죽지 않는다.)


두번째 그림

자식 프로세스가 (종료)리턴해 준 값을 커널이 부모 프로세스에게 주고 자식 프로세스를 종료한다.

부모 프로세스는 자식 프로세스의 (종료)리턴 값을 달라고 요구해야 좀비 프로세스가 생성되지 않는다.


※ int main()에서 return 0;하는 이유

프로그램의 main은 프로세스 생성을 요구한다.

리턴의 의미는 커널이 제대로 종료했는 지 알기 위해 필요한 값이다.


좀비 프로세스의 생성 이유.

자식 프로세스는 부모 프로세스에게 실행 결과에 대한 값을 반환해야 한다.

부모 프로세스가 반환받지 않으면 자식 프로세스는 좀비 프로세스가 된다.


wait함수의 사용

#include<sys/types.h>

#include<sys/wait.h>

pid_t wait(int *status);

자식 프로세스를 기다린다. 자식 프로세스가 종료하지 않으면 무한 대기할 수도 있다.

리턴 : 성공시 자식 프로세스 ID, 실패시 -1

status : 다음 매크로 함수 이용

WIFEXITED(status) : 정상 종료시 0을 반환

WEXITSTATUS(status) : 종료시 return하거나 exit함수의 인자로 넘겨진 값을 반환한다.


좀비 프로세스 소멸

소멸 방법 : 부모 프로세스에서 자식 프로세스의 반환 값을 요구한다.


waitpid함수의 사용

#include<sys/types.h>

#include<sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

참고주소 : http://linux.die.net/man/2/waitpid

리턴 : 성공시 종료된 자식 프로세스 ID, 실패시 -1

option이 WNOHANG이고 상태가 변한 프로세스가 없으면 0을 리턴.

pid 

-1이면 임의의 자식 프로세스가 종료하기를 기다리게 된다.

0이면 호출한 프로세스의 아이디와 같은 그룹일 경우.

0이상이면 기다리길 원하는 자식 프로세스의 ID. 

status : wait 함수의 status와 동일.

WNOHANG : 종료한 자식 프로세스가 없는 경우 대기 상태로 들어가지 않고 바로 리턴.


10-4. 시그널(Signal) 핸들링 & 좀비(Zombie) 프로세스

어떻게 효율적으로 좀비 프로세스를 처리할까?

부모 프로세스 입장에서 좀비(자식) 프로세스가 발생하는 시점을 모르기 때문에 (시스템은 알고 있음.)

운영체제가 시그널을 보내 부모 프로세스가 그 시그널을 읽어서 (시그널 핸들러를 통해) 자식 프로세스를 처리.


시그널

시스템 내의 특정상황 발생을 알리기 위해서 커널이 전달하는 신호. (운영체제에 의해 약속된 상수.)

시그널 핸들러

적절한 처리를 해 주는 함수

시그널 핸들링

시그널이 발생함에 따라 이에 대한 적절한 처리를 해 주는 것.


1. 자식 프로세스가 종료되었을 때(특정 상황) 부모 프로세스에게 시그널을 보냄.

2, 부모 프로세스는 시그널을 받으면 시그널 핸들러를 실행


signal 함수를 이용한 시그널 핸들링

signal함수

#include<signal.h>

void (*signal(int signum, void (*func)(int)))(int);

시그널(signum)과 시그널 핸들러(func)를 연결시켜주는 기능.

(해당 시그널 번호를 받으면 시그널 핸들러 함수가 실행된다.)

리턴이 void (*)(int); 함수 포인터 타입

리턴 : 오류시 SIG_ERR

signum

 시그널 발생상황 
 SIGALRM 시간을 예약해 놓고 그 시간이 되었을 경우 발생한다. 
 SIGINT Ctrl-C를 누를 경우 인터럽트 발생 
 SIGCHLD 자식 프로세스가 종료된 경우 발생. 


※ 시그널 핸들러에서 signal함수를 넣는 이유

운영체제가 시그널을 등록하면 딱 한 번만 signal함수를 호출하는 경우가 있기 때문에

※ signal로 시그널을 등록하지 않으면 운영체제에서 기본적으로 정의한 signal 핸들러가 호출된다.


sigaction함수

#include<signal.h>

시그널(signum)과 시그널 핸들러(func)를 연결시켜주는 기능. 이 함수를 사용하는 것을 추천.

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);


struct sigaction

{

    void (*sa_handler)(int);

    sigset_t sa_mask;    

    int sa_flags;

};


sa_mask

동시에 signal이 발생해도 처리할 수 있도록 한다. 

pending된 signal을 block, unblock시키는 용도로 사용.


sigemptyset : 시그널 마스크 비트(sa_mask)를 0으로 설정.


10-5. fork 함수를 이용한 다중 접속 서버의 구현


1. 클라이언트가 서버에게 연결 요청

2. 서버 프로세스가 연결 요청을 받을 때마다 자식 프로세스 생성 -> 자식 프로세스는 부모 프로세스가 전달한 디스크립터(client_sock)을 받는다.

3. 클라이언트와 자식 프로세스와 통신

※ 소켓은 운영체제가 관리하기 때문에 fork를 해도 복사되지 않는다. 파일 디스크립터는 복사가 된다.


파일 디스크립터의 복사

하나의 소켓에 대한 파일 디스크립터가 둘 이상 존재하는 경우, 모든 파일 디스크립터를 종료해 줘야 해당 소켓이 종료된다.

※ 커널에서 소켓은 참조카운트를 가지고 있을 듯...


부모 프로세스는 클라이언트 소켓이 필요없고 자식 프로세스는 서버 소켓이 필요없으므로 복제된 후 미리 삭제해 준다.


10-6. TCP 입출력 루틴(Routine) 분할하기

에코 클라이언트의 경우 적용 가능(그냥 하나의 모델로서... 소스가 복잡해 지는 단점이 있다.)

※ 송수신이 잦은 프로그램에 한해 효율성이 증가할 수 있다.


입력과 출력을 실행하는 루틴을 부모-자식 프로세스로 분리한다.

=> 입출력이 독립되어 다음과 같은 통신이 가능하다.


반응형
반응형

출처 : 

http://cafe.daum.net/svcom/4wrr/3?docid=1DW5t|4wrr|3|20080404111636&q=window%20messenger%20uninstall&srchid=CCB1DW5t|4wrr|3|20080404111636



[XP팁2] 메뉴팝업속도를 빠르게 하기

메뉴창이 열리는 속도가 느린것을 감지할수 있는데 빠르게 하는 방법이다.

HKEY_CURRENT_USER\ControlPanel\desktop

에서 MenuShowDelay 항목의 값이 기본 400으로 셋팅되어 있는데 이 값을 0 에서 400 사이에서 바꾼다. (0의 값이 최고 빠르다)

 

[XP팁3] 무응답 응용프로그램 타임아웃 시간줄이기

윈도우 XP는 해당 응용프로그램이 정지하면 해당 프로그램이 응답이 기다리는 시간이 설정되어 응답이 없으면 해당프로그램을 정지시킨다.

이 타임아웃시간을 조절해서 윈도우 XP 의 무응답 시간을 줄일 수 있다.

HKEY_CURRENT_USER\Control Panel\Desktop

에서 HungAppTimeout 값이 기본적으로 5000(5초)으로 설정되어있을 것이다.

이 값을 더블 클릭해서 1000 (1000 = 1초)로 설정해준다.

 

[XP팁4] 윈도우 창이 뜨는 속도 높이기

윈도우즈의 속도를 조금이라도 높이고 싶은 사람들에게는 창의 최대화 , 최소화에 따른 애니메이션 효과도 속도를 저하 시키는 원인이 될 것이다.

여기서는 그 속도를 높여주는 방법을 소개한다.

HKEY_CURRENT_USER\Control Panel\desktop\windowmetrics

로이동 우측 화면에서 마우스 오른쪽 버튼을 누른후 ``문자열 값``을 선택하고 MinAnimate라고 입력.

그다음 이 값을 더블클릭하여 값을 ``0``으로 설정.

이것으로 창이 열리거나 닫힐때 최대화 , 최소화 애니메이션 표시가 되지 않아 창의 표시속도가 눈에 띄게 빨라진다.

 

[XP팁5] 부팅시 NumberLock 설정방법

HKEY_CURRENT_USER\ControlPanel\Keyboard

에서 InitialKeyboardIndicators 항목의 키값을 2로 고침

 

[XP팁6] <시작>에서 문서메뉴 삭제하기

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer

오른쪽에 등록→DWORD값 에서 NoRecentDocsMenu 입력하고 값을 1로 입력.

 

[XP팁7] 다운로드 갯수 변경하는 방법

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings

이 키 또는 오른쪽 창의 빈 공간을 마우스 오른쪽 버튼으로 클릭하고 [등록]→[DWORD 값] 을 선택.

새 DWORD 값의 이름에 MaxConnectionsPerServer 라고 입력.

이 값을 더블클릭하고 값의 데이터 란에 원하는 다운로드 갯수를 입력.

 

[XP팁8] <시작> 에서 도움말메뉴 삭제하기

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer

이 경로에서 [새로만들기] 에서 [DWORD값]을 하나 만들고 이름을 [NoSMHelp]으로 한다.

더블 클릭해서 데이터 값을 1로 지정.

재부팅하거나 로그오프하면 설정이 적용.

복원은 값을 0으로 하면 된다.

 

[XP팁10] 익스플로러 시작시 풀스크린으로 항상 시작

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main

Main 항목 오른쪽 창에서 FullScreen 항목을 찾은후 더블클릭해서 no를 yes 바꾼다.

레지스트리 프로그램을 종료 후 재부팅 하면 끝.

익스플로어 공급자 이름 바꾸기

gpedit.msc 를 실행.

사용자 구성 - Internet Explorer 유지/보수 - 브라우저 사용자 인터페이스 - 브라우저 제목  에서 임의의 이름을 넣음.

HKCU\Software\Microsoft\Internet Explorer\Main

에서 Window Tile 을 바꿈.

윈도우 미디어 플레이어 목록 지우는 경로

HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Player __...

 

[XP팁16] 내컴퓨터의 [공유문서] 제거방법

컴퓨터에 보면 여러사용자가 공유할 수 있는 공유문서가 있다.

공유문서에는 공유그림 공유음악등이 있는데 필요하지 않는 경우 삭제할 수 있다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\DelegateFolders

에서 59031a47-3f72-44a7-89c5-5595fe6b30ee 를 찾아서 삭제(완전히 없어진건 아니고 보이지만 않을뿐이다).

 

[XP팁17] 지워도 보이는 프로그램목록지우기

프로그램 추가 에서 지우지 않고 그냥 프로그램의 언인스톨러를 제거했을때 프로그램추가 에서 목록이 그대로 남아있을 때가 있다.

그럴때는 지우지도 못하고 어쩔때는 설치가 잘 안될수도 있다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

에서 프로그램 추가에 있는 목록이 보일것이다.

그중에서 제거할 목록을 선택하고 삭제 하면 된다.

 

[XP팁25] 오류 보고(MS전송)창 나타나지 않게 하기

1) 시작->제어판->성능 및 유지 관리->시스템 

2) 시스템 등록정보창이 나타나면 [고급]탭에서 가장 아래에 있는 오류보고 버튼을 클릭한다. 

3) 오류보고 대화상자에서 `오류 보고 사용 안 함`을 선택하고 확인버튼을 누른다.

 

[XP팁26] 입력도구모음 없애기 

 

[제어판-국가및언어옵션-언어-자세히...-설치된서비스]에서 [한글입력기(IME2002)]만 있으면 [추가]를 

눌러서 [영어]를 추가해준다. 

[한글입력기(IME2002)]를 선택하고 [기본설정-입력도구모음]에서 모든 체크를 없애면 입력도구모음이 

없어진다.(추가한 영어는 제거한다) 

한자를 쓸때 입력도구모음이 필요하면 [작업표시줄-오른클릭-도구모음-입력도구모음]에 체크하면 다시 

나타난다.

 

[XP팁27] 폴더창 속도향상하기

제어판에서 ``폴더옵션``을 실행한 다음, ``보기`` 메뉴탭을 선택하고 ``고급설정`` 부분에서 

``폴더 및 바탕화면 항목에 팝업 설명 표시``와 ``압축된 파일과 폴더를 다른 색으로 표시`` 그리고 

``독립된 프로세스로 폴더창 실행``의 체크를 해제하여 속도 향상

 

[XP팁28] 빠른 웹서핑을 위한 인터넷 익스플로러 최적셋팅법   

도구 - 인터넷 옵션 - 고급에서 다음과 같이 해 보세요. 

탐색에서 "예약시 동기화할 오프라인 항목 표시" 해제 (선택하지않음) 

특정파일이(이름이 한글로 된 파일) 안열린경우 " URL을 항상 UTF-8로 보냄" 해제 (선택하지않음) 

탐색에서 "프록시 연결을 통해 HTTP 1.1 사용" 해제 (선택하지않음) 

연결항목 랜설정항목에서... 자동구성과 프록시 서버를 모두 해제 (선택하지않음)

 

[XP팁29] 임시인터넷 파일크기 최대한 줄이기

임시인터넷파일 보관폴더의 적정크기는 100MB~200MB정도가 가장 이상적이라고 한다.

 

[XP팁30] 내컴퓨터등 기본아이콘 보이게하기

XP를 설치하고나면 바탕화면에 휴지통만 보인다. XP의 시작그룹속에 모투 내장되었기 때문인데 이전처럼 

바탕화면에 기본아이콘이 보이게 할려면 바탕화면에서 오른쪽마우스클릭-->속성-->바탕화면-->바탕화면사용자지정

-->내바탕화면아이콘에서 필요 항목 체크인하면 된다.

 

[XP팁34] Windows Messenger 삭제하는 방법

Windows Messenger 이외의 다른 메신저 프로그램을 사용하는 사람에게는 불필요한 프로그램이다.

이 프로그램을 삭제하는 옵션을 윈도우에서는 기본적으로 제공하지 않는다. 하지만 약간의 inf 파일 수정을 통해서 삭제할 수 있다.

1.windows/inf/sysoc.inf 폴더를 메모장으로 연다.

(시작 버튼 -> 실행 하면 다음과 같이 나오는데 밑에 처럼 입력한 후 확인을 누릅니다.)


2.msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,hide,7-->이 라인을 찾아서 아래와 같이 변경하고

msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,7-->hide,만 제거한후 저장한다.

3.위와 같이 변경하고 시작->제어판->프로그램 추가/제거->windows 구성요소 추가/제거에 Windows

Messenger체크 옵션이 나타난다. 여기에 체크를 아웃하면 삭제된다.

추가적으로 msn익스플러도 삭제할 수 있다.

 

[XP팁39] MSN Explorer제거방법

1. [시작]-[모든 프로그램(P)]를 선택하고 MSN Explorer 아이콘 위에 커서를 갖다 댄다.

2. 오른쪽 마우스 버튼을 클릭한 후 [속성(R)]을 선택

3. "MSN Explorer 등록정보" 창이 뜨면 아랫부분에 있는 [대상 찾기(F)]를 선택

4. 지금까지의 과정을 밟아 왔다면 MSN Explorer의 폴더로 이동을 해 있다. 거기에 폴더가 두 개가 있는데,

   Setup이란 폴더를 열어 보면 msnunin이란 프로그램이 있는데, 이게 MSN Explorer의 "제거 프로그램" 이다.

   클릭하면 시작 메뉴에 있는 "바로 가기"를 비롯해서 모든 게 제거.

 

[XP팁42] DirectX 버전 확인방법

시작 - 실행에서 dxdiag 라고 쓴 후 엔터.

(dxdiag : DirectX 진단도구 실행 명령어)

 

[XP팁43] 자신의 윈도 엑피가 정품 인증 확인방법

시작 -> 실행->oobe/msoobe /a (슬래시 a 앞에 한칸을 띄우는것을 주의..)

 

[XP팁46] 방화벽설정/제거방법

윈도우 XP는 인터넷 연결방화벽 설정 부분이 있어서 다른 컴퓨터가 내 컴퓨터를 엑세스하는 것을 막을 수 있다.

하지만 나누미나 P2P프로그램을 사용하는 경우 사용자가 컴퓨터에 접근할 수 없게 된다.

이럴경우 방화벽을 제거해주어야 한다.

 

바탕화면의 네트워크환경의 등록정보를 연다-자신의 네트워크 연결항목 을 선택하고

마우스우측버튼을 클릭해서 등록정보를 열면 창이 나오는데,

고급-인터넷 연결방화벽을 체크하던지 체크아웃한다.

 

[XP팁47] 종료로고만 나오고 전원안꺼질때

(조치1) 제어판(control panel)-전원 옵션(power options)-APM탭-하단의 [Enable Power Management  support](최대 절전모드사용) 를 체크.

APM지원을 체크한다.

 

(조치2) CMOS에서 전원관리 부분에 가서 "PM Control by AP" 를 YES라고 변경한다.

 

(조치3) 제어판-새 하드웨어 추가 를 클릭한다.

하드웨어 추가 마법사 - 다음 을 눌러 윈도우 XP가 새로 설치된 장치를 찾으면 하드웨어가 연결되어 있습니까? 하고 물어 보는데,

예, 하드웨어를 연결했습니다 선택하고 다음 을 누른다.

설치된 하드웨어 - 새 하드웨어 장치 추가 를 선택하고 다음 을 누른다.

원하는 작업을 선택하십시오 라고 나오면 목록에서 직접 선택한 하드웨어 설치(고급) 을 선택하고,

다음 을 클릭.

일반 하드웨어 종류 에서  NT APM/레거시 지원 을 선택하고 다음 을 누르고,

하드웨어 추가 마법사를 계속 따라 하면 무사히 설치.

 

 

반응형

'도움받은 정보' 카테고리의 다른 글

숨김파일 표시 안될 때  (0) 2010.03.23
고속도로와 소방서  (0) 2010.03.19
Virtualbox could not create temporary directory.  (0) 2009.07.28
네로 서치 제거법  (0) 2009.07.28
구조체 정렬, __attribute__ ((packed))  (0) 2009.07.28
반응형
VirtualBox 3.0 버젼을 윈도우 XP에 설치시 나는 에러입니다.
2.2 버젼에도 발생하는 에러더군요.
이유는... 저 너머에 있겠지만 해결방법입니다.

내 컴퓨터 -> C:\
로 가셔서
TEMP라는 이름의 폴더를 만듭니다.

C:\TEMP

내컴퓨터 -> 마우스 우측클릭 -> 고급 -> 환경 변수



환경변수에서
TEMP와 TMP 변수에 대해 '편집' 버튼을 누른 후 
위와 같이 입력해 주시면 됩니다.

반응형

'도움받은 정보' 카테고리의 다른 글

숨김파일 표시 안될 때  (0) 2010.03.23
고속도로와 소방서  (0) 2010.03.19
윈도우XP 최적화 팁 모음  (0) 2009.07.28
네로 서치 제거법  (0) 2009.07.28
구조체 정렬, __attribute__ ((packed))  (0) 2009.07.28
반응형
regsvr32 /u /s "C:\Program Files\Common Files\Ahead\Lib\NeroSearch.dll"
regsvr32 /u /s "C:\Program Files\Common Files\Ahead\Lib\NeroSearchBar.dll"
regsvr32 /u /s "C:\Program Files\Common Files\Ahead\Lib\NeroSearchTray.dll"
반응형
반응형

출처: 지식IN(edson)

http://cafe.naver.com/devctrl.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=3272




__attribute__는 GCC 컴파일러에 있는 메커니즘으로 컴파일러에게 추가적인 에러 체킹같은 것을 하도록 지시하는 것이다.

 

형식 : __attribute__ (x)

 

괄호 안의 x에는 가능한 몇 가지들이 있다. 특히, packed는 채우라는 의미이다.

 

typedef struct

{

    char a;

    int b;

} myST;

 

위 구조체의 sizeof(myST)는 8이다.

상식적으로, char =1byte, int = 4byte이므로, 5가 나와야 하는데.. 이런 문제때문에, 구조체를 가지고 작업할 경우 예상치 못한 버그로 고생을 가끔한다.

이런 현상이 생기는 이유는, 현재 사용하는 컴퓨터는 32비트이다. 즉, CPU가 메모리 어드레스를 지정할 때 4바이트(32비트/8) 단위가 내부적으로 가장 최적화되어 빠른 데이터 접근을 가능하게 한다. 4바이트 배수 단위가 아닌 경우 당연히 접근은 가능하지만 속도 차이가 있어, 디폴트로 저런 접근을 하도록 해 둔 것이다. 

 

그럼, 메모리에 저 구조체가 잡힐 경우 어떻게 존재하느냐는, 4바이트 단위로 채워지기 때문에, char a;는 1바이트이지만, 4바이트를 할당해서 거기다 char a;를 담아둔다. 다음, int b;는 4바이트므로 그냥 4바이트를 할당한다. 이렇게 해서 8바이트의 크기가 필요한 것이다. 

 

첫 char a;에서 1바이트를 제외한 나머지 3바이트는 어떤 걸로 채워질까? 의미없는 값이 채워진다. 그냥 공간만 예약되는 것이다.

그래서, 이런 현상을 방지할 수 있도록, 컴파일러는 __attribute__ ((packed)) 메커니즘을 두어서 우리가 예상한 1바이트+4바이트, 크기가 되도록 빌드한다. 

 

typedef struct

{

    char a;

    int b;

} __attribute__ ((packed)) myST;

 

결국, 위 처럼 사용하게되면, 컴파일러는 구조체 멤버 실제 크기 만큼 할당한다. 그래서 정확한 5바이트가 나오게된다. 물론, 속도는 약간 더 늦어진다. 

 

여기에서 __attribute__라는 의미는 , 컴파일러에게 특성을 주겠다는 것을 의미하며 괄호 안은 여러 가지가 가능한데, 여기서는 그 중 한가지인 구조체 정렬을 사용하겠다는 의미인 packed를 사용했다.

 

packed의 의미는 꽉 채우다라는 것인데,  이 기능을 사용하지 않았을 경우 char a;는 실제 1바이트 외에 나머지 3바이트가 자리만 차지한 채 남아있다. 이런 비어있는 것들을 제거해서 구조체 멤버들이 빈 자리없이 꽉 채우라는 단어 의미이다. 이런 것을 구조체 정렬(alignment)이라고 한다. 

 

위는 unix/linux의 GCC에서 사용하는 것이고 윈도우 상의 비주얼 씨의 경우는

#pragma pack(1)

처럼 사용한다. 괄호 안의 의미는 1바이트 단위까지 체크해서 빈 자리없도록 차곡차곡 채우라는 것이다. 4가 올수도 있겠지만, 그렇게 되면 가장 작은 단위가 4가되어 char 형 같은 경우 역시 4로 채워지게 되어 낭패이다. 따라서 확실한 경우 아니면, 위 처럼 사용하면 된다.

 


반응형

'도움받은 정보' 카테고리의 다른 글

숨김파일 표시 안될 때  (0) 2010.03.23
고속도로와 소방서  (0) 2010.03.19
윈도우XP 최적화 팁 모음  (0) 2009.07.28
Virtualbox could not create temporary directory.  (0) 2009.07.28
네로 서치 제거법  (0) 2009.07.28
반응형

9-1 소켓의 옵션

1. 소켓의 옵션 조작 : 소켓의 기본적인 특성(다양함)을 변경하는 것.

※ 운영체제에 의해 관리. 운영체제는 소켓의 특성에 대한 정보를 보관하고 있다.

2. 소켓의 기본적인 특성

 - 입력 및 출력 버퍼의 크기

 - 데이터 전송 방식(TCP 또는 UDP)

 - TTL(Time To Live) : 건너뛸 수 있는 라우터의 개수. hop과 관련됨.

3. 옵션은 대부분 변경(set) 가능하지만 참조(get)만 가능한 것도 있다.


소켓의 옵션 관련 함수

1. 현재 설정 상태 정보를 가져오는 함수.

#include <sys/types.h>

#include <sys/socket.h>

int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);

sock : 소켓을 나타내는 디스크립터

level : 확인할 옵션의 프로토콜 레벨

optname : 확인할 옵션의 이름

optval : 원하는 옵션의 이름의 값을 얻음.

optlen : optval 포인터가 가리키는 버퍼의 크기.


#include<winsock2.h>

int getsockopt(SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen);

s : 소켓 핸들


2. 옵션을 변경하는 함수.

#include<sys/types.h>

#include<sys/socket.h>

int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);

sock : 소켓을 나타내는 디스크립터

level : 변경할 옵션의 프로토콜 레벨

optname : 변경할 옵션의 이름

optval : 원하는 옵션의 값을 저장한 포인터 전달.

optlen : optval 포인터가 가리키는 버퍼의 크기.


#include<winsock2.h>

int setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen);

s : 소켓 핸들


소켓의 옵션

Protocol Level(프로토콜 레벨) : 옵션이름을 그룹짓기 위해 필요.

SOL_SOCKET : 일반적인 소켓의 옵션.

IPPROTO_IP : IP에 대한 소켓의 옵션.

IPPROTO_TCP : TCP에 대한 소켓의 옵션


※ SO_TYPE 옵션 : 소켓의 타입 정보(TCP(1)/UDP(2))값을 얻는다. 다시 재설정할 수 없다.

윈도우즈용 프로그램


9-2 SO_SNDBUF & SO_RCVBUF

getsockopt함수를 통해서 디폴트 버퍼의 크기를 구할 수 있다.

※ 리눅스 시스템 마다 입력 버퍼, 출력 버퍼의 크기는 다르다.

내 컴퓨터 우분투의 경우

입력버퍼 : 87380

출력버퍼 : 16384


setsockopt함수를 통해서 버퍼의 크기를 변경할 수 있다.

※ 바꿀 수 있는 최소 버퍼의 크기는 정해져 있다

※ 버퍼가 없으면 TCP를 할 수 없기 때문에 0으로 설정해도 최소값으로 바뀌어서 버퍼의 크기가 설정된다. 성능과 직결되는 문제이다.


9-3. SO_REUSEADDR

TIME_WAIT 상태?

연결 종료시 마지막 패킷 전송 실패를 대비하기 위한 상태


종료를 먼저 요청한 호스트가 나중에 소켓을 소멸시킨다. 

마지막 ACK 신호가 잘 전달되지 않았을 때를 대비해서 TIMEOUT이 존재한다.

이유 : 상대방(B)의 종료 요청(FIN)을 기다리는 데 걸리는 TIMEOUT이다.


서버의 연결 종료

서버에서 먼저 종료 요청 후, 다시 서버를 가동시키면?

서버가 종료 메세지를 보내고 TIMEOUT 시간동안은 서버 재가동 불가. 

이유 : 그 아이피와 포트가 사용중이기 때문.


TIME_WAIT 타이머의 재시작

TIME-WAIT 상태는 우리의 생각보다 더 길어 질 수 있다.


마지막 ACK신호를 못 보낼 경우 다시 FIN을 보낼 때 다시 TIMEOUT을 설정해야 되기 때문이다.


※ TIMEOUT이 걸린 소켓이라고 그 주소와 포트에 다시 소켓을 만들 수 있게 설정한다.

server_socket = socket(PF_INET, SOCK_STREAM, 0);

option = sizeof(option);

option = TRUE;

setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));


9-4. TCP_NODELAY

네트워크 상의 패킷 수를 줄이기 위해 제안된 알고리즘

ACK을 수신해야만 다음 전송을 진행하는 알고리즘.

※ ACK이 올 때까지 보낼 내용은 버퍼에 쌓아 둔다. (전송버퍼가 필요한 이유)

예시) "agle"은 버퍼에 쌓여 있다가 보내진다.

※ nagle 알고리즘이 off면 데이터가 오면 무조건 상대방에게 보낸다.


Nagle 알고리즘의 장점과 단점

장점 : 네트워크의 효율성이 높아진다. (적은 패킷의 양)

단점 : 전송 속도가 느리다. (ACK 수신 후 패킷 전송)

생각해 볼 문제 : Nagle 알고리즘의 중단이 데이터 전송 속도를 무조건 향상 시켜주는 것은 아니다.

※ 네트워크 트래픽 양이 많다면 (차가 많으므로)속도가 꼭 빨라지지는 않을 수 있음.


TCP_NODELAY

serv_sock = socket(PF_INET, SOCK_STREAM, 0);

opt_val = TRUE;    // option 값이 TRUE면 nagle알고리즘 off 됨.

setsockopt(serv_sock, IPPROTO_TCP, TCP_NODELAY, &opt_val, sizeof(opt_val));

반응형
반응형

8-1. DNS(Domain Name System)

1) 도메인 이름이란? 

1. 영문으로 표현되는 계층적 주소 체계 방식.

※ IP 이후에 도메인이 나왔음. 중복되면 안 된다.

2. 각 나라마다 존재하는 Network Information Center에서 관리. => 약속

한국은 KRNIC(http://www.nic.or.kr, Korea Network Information Center)에서 담당.

3. 도메인 이름 = 호스트 이름 + 도메인 이름

예시) academy.freelec.co.kr = academy + freelec.co.kr

4. TCP/IP는 도메인 이름을 인식 못함.

※ IP와 도메인의 중계 역할을 하는 서버 : 도메인 서버


현실세계의 주소체계


인터넷 상에서의 주소체계

root 도메인

com : 회사, zw : 짐바브웨, kr : 한국

2차 도메인

co : 나라 안의 기업, ac : 나라 안의 대학, or : 행정기관, 


2) DNS 서버

1. 모든 도메인 이름은 해당 IP와 함께 DNS 서버에 등록되어야 한다.

※ DNS 서버는 테이블 형식으로 정보를 가지고 있다.

2. 도메임 이름을 IP 주소로 변환해 주는 작업을 한다.


1. host는 DNS 서버에 도메인 주소 질의

2. DNS 서버는 테이블 정보를 검색하여 IP를 답변해 준다.

※ 분산 데이터베이스 : 모르면 다른 DNS 서버에 물어본다.

3. host는 받은 IP정보를 통해 원하는 도메인 주소로 접속한다.


도메인 이름과 IP변환 과정

※ DNS 서버는 계층적 구조로 되어 있다. 모를 경우 부모에게 물어본다. 

루트 DNS는 모든 주소에 대한 정보를 어느 자식에 있는 지 알고 있다. (자손까지는 아님.)


8-2 IP 주소와 도메인 이름 사이의 변환

변환(도메인 이름 <-> IP주소)의 필요성

상대적으로 잦은 IP 변화에 대한 능동적인 문제 해결

※ IP를 하드코딩하면 IP주소가 바뀌었을 때는 접속할 수 없기 때문에 도메인 이름을 하드 코딩하여 IP가 바뀌더라도 도메인 이름으로 접속할 수 있도록 한다.

※ 한 도메인에 대해 IP를 여러 개 두고 상황에 따라 분산하여 접속할 수 있게 한다.


도메인 이름->IP주소 함수

※ 함수 자체가 DNS 서버에게 물어보고 IP주소등의 정보가 리턴된다.


#include<netdb.h>

struct hostent* gethostbyname(const char* name);

name : 도메인 이름 문자열


#include<winsock2.h>

struct hostent FAR *gethostbyname(const char FAR *name);

name : 도메인 이름 문자열


struct hostent 구조체 


struct hostent

{

char *h_name;

char **h_aliases;

int h_addrtype;

int h_length;

char **h_addr_list;

};


공식 이름(official name)

별명 목록(alias list)

호스트 주소 형태(host address type)

주소의 길이(IPV4 : 4, IPV6 : 16)

주소 목록(list of addresses)

struct hostent

{

char FAR * h_name;

char FAR * FAR * h_aliases;

short h_addrtype;

short h_length;

char FAR * FAR * h_addr_list;

}


※ IP주소를 일반화 하기 위해 char*를 사용하였다. IN_ADDR 구조체 형태로 IP주소가 저장되기 때문에 void* 포인터 형태가 더 좋았을 듯.


struct hostent 구조체 변수


반응형
반응형

※ 연결에 대한 내용이므로 TCP/IP 프로토콜에 대한 이야기.

※ 우아한 종료 = graceful close. (MSDN 참고)


7-1 소켓 연결 종료의 문제점

2개의 가상의 통로가 생성 (각 통로는 단방향)


스트림 : 연결된 상태 (데이터를 주고 받을 수 있도록 연결된 시스템의 내부적인 상황)

입력 스트림 : 데이터 수신을 위한 스트림

출력 스트림 : 데이터 전송을 위한 스트림


※ TCP 소켓은 데이터를 전송하면서 동시에 수신도 가능하다.


소켓 연결 종료의 문제점

1. close, closesocket 함수 호출 : 입력, 출력 스트림 완전 종료

 => 데이터를 송수신 할 수 없다. 데이터가 소멸된다.

2. 일방적인 방식의 완전 종료는 경우에 따라서 문제가 될 수 있다.



7-2 우아한 소켓의 연결 종료

half close : 입력 혹은 출력 스트림 중 하나의 스트림만 종료하는 행위

예시) A 호스트의 출력 스트림만 종료

#include <sys/socket.h>

int shutdown(int s, int how);

리턴 : 성공시 0, 실패시 -1

s : 종료하고자 하는 소켓의 파일 디스크립터

how : 종료 모드를 인자로 전달한다.

 상수값 모드 정의 
 0  SHUT_RD  입력 스트림 종료 
 1  SHUT_WR 출력 스트림 종료 
 2  SHUT_RDWR  입출력 스트림 종료


출력 스트림의 종료의 필요성

※ Thank you를 받기 위해 shutdown함수를 사용한다.


1. 출력 스트림을 종료하게 되면, 연결되어 있던 호스트로 EOF 메세지 전달.

※ 출력 스트림을 종료하는 방법 : close(closesocket), shutdown 함수.

2. EOF 전송으로 데이터 전송의 끝을 알려 줄 수 있다.

3. EOF 전송 시, 상대 호스트의 데이터 수신 함수(read, recv)는 0을 리턴.


※ EOF를 생략하고 보내면 서버도 read() 무한 대기, 클라이언트도 파일의 끝을 모르므로 read() 무한대기.


※ EOF의 값 : -1 (int type) -> 1바이트를 4바이트로 casting하면 -1이 아닐 수 있다.


7-3. 윈도우즈 기반으로 구현하기

※ 윈도우즈 기반에서는 파일 열기를 위해 표준 라이브러리를 사용하였다.


#include <winsock2.h>

int shutdown(SOCKET s, int how);

리턴 : 성공시 0, 실패시 SOCKET_ERROR

s : 종료하고자 하는 소켓의 파일 디스크립터

how : 종료 모드를 인자로 전달한다.

 상수값 모드 정의 
 0  SD_RECEIVE 입력 스트림 종료 
 1  SD_SEND 출력 스트림 종료 
 2  SD_BOTH 입출력 스트림 종료

반응형
반응형

※ TCP와 UDP를 특징을 비교하면서 공부하는 것이 좋다.

6-1. UDP의 이해

1. IP를 기반으로 데이터를 전송한다. (TCP와 공통점)

2. 흐름제어(flow control)을 하지 않기 때문에 데이터 전송을 보장 받지 못한다. (TCP와 차이점)

3. 연결설정 및 연결 종료 과정도 존재하지 않는다. (TCP와 차이점)

4. 연결 상태가 존재하지 않는다. (TCP와 차이점)


UDP의 역할

포트 정보에 의한 프로세스의 구분

UDP 패킷 = 데이터 그램(Datagram)


6-2. UDP 기반 서버/클라이언트의 구현

※ 소켓을 생성하고 bind까지만 하면 바로 입출력함수를 사용하면 된다. 

(socket~bind : 서버, socket : 클라이언트)

일반적으로 연결 설정 과정을 거치지 않는다.

데이터를 주고 받기 위한 소켓(우체통에 비유)은 하나만 생성해도 된다. (패킷은 우편)


※ UDP는 비연결 프로토콜이기 때문에 주소 정보를 알아야 한다.

데이터 전송함수

int sendto(int sock, const void* msg, int len, unsigned flags, const struct sockaddr *addr, int addrlen);

int sendto(SOCKET s, const char FAR *buf, int len, int flags, const struct sockaddr FAR *to, int tolen);

1~4번째 인자는 TCP send함수와 비슷.

addr : 목적지 주소 정보

addrlen : 목적지 주소 정보 구조체 크기


데이터 수신함수

int recvfrom(int sock, void *buf, int len, unsigned flags, struct sockaddr *addr, int *addrlen);

int recvfrom(SOCKET s, char FAR *buf, int len, int flags, struct sockaddr FAR *from, int FAR *fromlen);

1~4번째 인자는 TCP recv함수와 비슷.

addr : 목적지 주소 정보

addrlen : 목적지 주소 정보 구조체 크기


※ uecho_client_win.c : 윈도우 UDP 에코 클라이언트는 리눅스 용과 다르게 제작되어 있음.

※ UDP에서 클라이언트의 주소는 언제 할당될까? 6-4에 있음.


6-3. 데이터의 경계(boundary)가 존재하는 UDP 소켓

UDP 소켓은 데이터를 송수신하는데 필요한 함수 호출의 수를 정확히 일치 시켜야 한다.


6-4. connect 함수 호출을 통한 성능의 향상

1. TCP 소켓에서의 connect 함수의 의미

 - IP와 포트의 할당

 - Three-way handshaking

2. UDP 소켓에서의 connect 함수의 의미

 - IP와 포트의 할당

※ connect함수가 없으면 sendto 함수가 제일 처음 호출되는 시점에 IP와 Port가 할당된다. 

클라이언트에서 IP와 Port가 한 번 할당되면 close()함수 호출시까지 변하지 않는다.


TCP/UDP 소켓에서 공통적으로 가지는 connect의 의미


connect함수의 의미 

커널과 소켓이 논리적으로 연결하고 그것을 유지한다.


connect함수를 호출하지 않을 때 UDP 클라이언트의 데이터 송수신

1. sendto, recvfrom 함수를 호출하면 커널과 소켓이 연결되고 소켓과 호스트와 통신할 준비를 한다.

2. 호출이 끝나면 커널과 소켓의 연결이 해제된다.

※ 위의 1~2를 반복하는 데 많은 시간을 잡아먹고 커널과 소켓을 연결했다 해제했다 하기 때문에 성능 효율이 떨어진다.


connect 함수 호출이 주는 이점

1. 데이터를 주고 받는 속도가 빨라진다.

2. TCP 소켓 기반의 데이터 입출력 함수를 그대로 사용할 수 있다.


반응형

+ Recent posts