SlideShare une entreprise Scribd logo
1  sur  63
[IGRUS] -pineoc 이윤석
 주요 챕터
 각각의 챕터에 대한 이론
 코드 및 설명
 공부하면서 배운 것, 느낀점.
 Ch3. 파일 다루기
 Ch11.프로세스와 신호
 Ch12.쓰레드
 Ch13.프로세스간 통신 : 파이프
 Ch14. 세마포, 공유 메모리, 메시지 큐
 Ch15. 소켓
 파일과 디렉토리를 다루는 여러 가지 함수들을 상
세히 설명하는 데 주력.
◦ 파일과 장치
◦ 시스템 호출
◦ 라이브러리 함수
◦ 파일 다루기
◦ 표준 I/O 라이브러리
◦ 입,출력 서식화
◦ 파일과 디렉터리 관리
◦ 디렉터리 탐색
◦ 오류처리, /proc 파일 시스템, fcntl과 mmap
 저수준 파일 접근
하나의 프로그램이 시동될 때에는 일반적으로 세 개의 파일 서술자들이 이미
열린 상태이다.
- 0 : 표준 입력
- 1 : 표준 출력
- 2 : 표준 오류
위의 파일 서술자는 자동으로 열리며, 따라서 프로그램은 별다른 절차 없이
Write를 이용, 즉시 해당 장치에 자료를 기록할 수 있다.
 Write
Write 시스템 호출은 버퍼 buf에 있는 처음 nbytes 개의 바이트들을
파일 서술자 fildes에 연관된 파일에 기록하고, 실제로 기록한 바이트 수를 돌
려준다.
시스템 호출의 구문
#include <unistd.h>
Size_t write(int fildes, const void* buf, size_t nbytes);
 Read
Read 시스템 호출은 파일 서술자 fildes에 연관된 파일로부터 nbytes개의 바
이트들을 읽어서 그 바이트들을 버퍼 buf에 집어넣는다.
반환값은 실제로 읽은 바이트 개수인데, 요청한 바이트 수보다 작을 수도 있다.
반환값이 0이면 아무 것도 읽지 않은 것이다(파일의 끝에 도달한 경우).
-1 은 오류를 의미
#include <unistd.h>
Size_t read(int fildes, void *buf,size_t nbytes);
 Open
새 파일 서술자를 만들기 위해서는 open 시스템 호출을 사용해야 한다.
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
Int open(const char* path, int oflags);
Int open(const char* path, int oflags, mode_t mode);
간단히 말하자면 open은 파일 또는 장치로의 접근 경로를 만듬.
Flag값을 통해 모드 설정, O_RDONLY, O_WRONLY, O_RDWR
각각 읽기, 쓰기, 읽기 쓰기 가능하게 하는 모드.
(이들 중 하나를 반드시 지정해야 한다.)
(다른 플래그 값이 있지만 상세한 부분은 생략한다.)
 초기 권한
그림에서 보듯이, drwxrwxr-x :디렉토리, 사용자,그룹,다른 사용자
R은 읽기권한, w는 쓰기, x는 실행 이다.
이 후에 close 함수, ioctl 함수가 있는데 close는 파일 서술자와 파일의 연관
을 끊는 함수, ioctl함수는 파일 서술자(fildes)가 가리키는 대상에 대해
cmd로 지정된 기능을 수행한다.
 나머지 파일 관리 관련 시스템 호출들
-lseek : 파일 서술자(fildes)가 가리키는 파일의 읽기/쓰기 포인터 설정한다.
-fstat,stat,lstat : 파일서술자에 연관된 파일의 상태 정보를 돌려준다.
-dup, dup2 : 파일 서술자를 복제하는 데 쓰인다.
이 호출들에 대한 변수나 자세한 사항은 참조하여 사용한다.
 표준 I/O 라이브러리
->표준 I/O 라이브러리와 해당 헤더 파일은 저수준 I/O 시스템 호출들에 대한 융통성
있는 인터페이스를 제공한다. 아래에 설명할 부분은 저수준 시스템 호출이다.
-fopen : 이 함수는 주로 파일과 터미널의 입.출력에 쓰인다. 장치들을 좀 더 명시적으
로 제어하려면 저수준 시스템 호출을 사용하는 것이 좋다.
-fread : 파일 스트림으로부터 자료를 읽는데 쓰인다. 읽은 자료는 ptr이 가리키는 자료
버퍼에 기록된다.fread, fwrite 모두 자료를 레코드 단위로 처리한다.
-fclose : 스트림 매개변수로 지정된 스트림을 닫는다. 이때 아직 기록되지 않은 자료가
모두 기록된다.명시적으로 사용해주면 좋다.
-fwrite : 인터페이스는 fread와 비슷하다. 출력 스트림에 기록, 성공적으로 기록한 레코
드 개수를 돌려준다.
-fflush : 주어진 파일 스트림에 대해 대기 중인 모든 자료를 즉시 기록한다.
예) 대화식 프롬프트가 확실히 터미널에 출력된 후에만 사용자의 입력을 받아 들여야하
는 경우에 유용.fclose 호출하는 시점에서는 fflush를 굳이 호출할 필요가 없다.
*헤더파일은 stdio.h 이다.
 표준 I/O 라이브러리
-fseek : 시스템 호출 lseek에 해당. 이 함수는 스트림에서 다음번에 자료를 읽거나
쓸 위치를 설정한다. 차이점은 lseek은 off_t, fseek은 성공시 0, 실패시 -1 반환한다.
-fget, getc, getchar : 파일 스트림에서 다음 바이트(문자)를 돌려준다. 파일의 끝에
도달했거나 오류가 있다면 EOF를 돌려준다.
-fputc, putc, putchar : fputc는 문자 하나를 출력 스트림에 기록한다. 성공 시 문자의
값을 돌려주고, 실패 시 EOF를 돌려준다.
-fgets, gets : 입력 파일 스트림에서 하나의 문자열을 읽어 들인다.
Ex) char* fgets(char* s, int n, FILE* stream);
char* gets(char* s);
->s가 가리키는 문자열에 넣되 새 줄 문자를 만나거나, n-1개의 문자들을 읽었거나, 파
일의 끝에 도달하면 멈춘다. 새 줄 문자도 s에 저장된다.
*EOF는 End Of File의 약자
 서식화된 입력과 출력
-printf, fprintf, sprintf : 서로 다른 형식의 여러 인수들을 서식화해서 출력한다.
-scanf, fscanf, sscanf : 스트림으로부터 값들을 읽고 그것들을 포인터 매개변수들이
가리키는 변수들에 집어넣는다.
-기타 다른 함수들도 많지만 (표준 스트림 stdin, stdout,stderr 을 사용하는 함수들)
파일 스트림에 대한 설정이나 위치설정 등이다.
 파일과 디렉터리의 생성 및 관리
-파일, 디렉터리의 생성 및 관리를 위한 여러 표준 라이브러리 함수들과 시스템 호출.
-chmod : 시스템 호출로, 파일이나 디렉터리의 접근 권한을 변경하는 데 쓰인다.
-chown : 슈퍼사용자는 이 시스템 호출로 파일의 소유자를 변경할 수 있다.
-unlink : 파일의 제거.
-mkdir, rmdir : 디렉토리의 생성, 제거. 권한 설정은 umask에 의존한다.
-chdir 와 getcwd : 현재 디렉토리 변경 시 chdir 시스템 호출. 현재 디렉토리를 알고
싶을 때는 getcwd함수 사용.
-opendir : 디렉터리를 열고 그에 대한 디렉터리 스트림을 만듬. 성공시 디렉터리 항목
들을 읽는데 사용할 DIR 구조체를 가리키는 포인터를 돌려준다.
-readdir : 디렉터리 스트림 안의 다음 디렉터리 항목에 대한 구조체의 포인터를 반환.
-telldir : 디렉터리의 스트림의 현재 위치에 해당하는 값을 돌려준다.
-seekdir : 주어진 디렉터리 스트림의 현재 디렉터리 항목 위치를 변경한다.
-closedir : 디렉터리 스트림을 닫고 그에 연관된 자원들을 해제한다. 성공 시 0 반환.
 오류처리
-strerror : 주어진 오류 번호에 해당하는 오류 메시지 문자열을 반환한다.
-perror : 오류 번호를 직접 받는 대신 현재 errno에 설정된 값을 사용.
 /PROC 파일 시스템
->이 파일 시스템이 제공하는 것은 드라이버들과 커널 기능.
 Fcntl 과 mmap
->fcntl은 저수준 파일 서술자를 통해 파일을 좀 더 세밀하게 제어.
->mmap 둘 이상의 프로그램들이 읽거나 쓸 수 있는 메모리 영역을 설정.
 프로세스와 신호에서 다루게 될 부분
◦ 프로세스 구조, 종류, 일정
◦ 새 프로세스를 시작하는 여러 가지 방법들
◦ 부모, 자식, 좀비 프로세스
◦ 신호와 그 활용 방법
 프로세스란…?
◦ “하나 이상의 스레드들과 그 스레드들에 필요한 시스템
자원들을 포함하는 하나의 주소 공간”으로 정의한다.
◦ 프로세스를 현재 실행 중인 하나의 프로그램으로 간주.
 프로세스 구조, 종류, 일정(스케줄링)
PID 101
CODE
자료
라이브러리
파일들
PID 102
CODE
자료
라이브러리
파일들
code
C라이브러리
Treck.txt nene.txt
$ grep 자료 treck.txt $ grep 자료 nene.txt
 프로세스 보기
프로세스의 상태
현재 실행중인 프로세스
 새 프로세스 시작
◦ System 함수를 이용한 프로세스의 시작. 여기선 clear 명령어를 사용했다.
 프로세스 이미지 대체하기
◦ Exec 함수를 이용, 새 프로세스를 띄우지만 프로세스를 띄우는 방식이나
프로그램 인수들을 제공하는 방식은 서로 다르다.
 System 함수보다 훨씬 효율적 -> 새 프로그램이 시작된 후에는 원래의 프로그
램이 더 이상 실행될 필요가 없다는 점에서 system 함수보다 훨씬 효율적.
 예) execl(const char* path, const char* arg0, … ,(char*)0);
Execlp를 이용한 ps ax 실행.
 프로세스의 이미지 복제(fork)
◦ 동시에 여러 기능을 수행하고자 할 때에는 제 12장에서 다루는 스
레드를 사용할 수도 있고, init이 하는 것처럼 한 프로그램 안에서
완전히 개별적인 프로세스를 생성 할 수도 있다.
초기 프로세스
Fork()
원래 프로세스
의 실행
새 프로세스
0을 리턴
새 PID 리턴
 Fork함수의 책에서의 간단한 예제
중간에 명령프롬프트가 껴있는데
그 이유는 자식 프로세스는 여전히 실행 중,
부모프로세스는 끝난 이유이다.
 좀비 프로세스
◦ Fork를 이용한 프로세스 생성은 유용하나, 실행이 종료되었으나 부모와
의 연관관계가 아직 남아 있는 프로세스를 가리켜서 소멸된(defunct)프
로세스, 좀비 프로세스라고 부른다.
실행 시 뒤에 & 붙여서 백그라운드 작업 후
부모 프로세스 끝나기 전에 ps 명령어를 실행시켜보면,
<defunct> 라고 나오며, 이것이 좀비 프로세스이다.
 쓰레드
◦ 리눅스에서 프로세스보다 작은 실행 단위로 스레드라는 것이 있다.
추후 ch12 에서 다룸.
 신호(signal)
◦ 신호는 유닉스와 리눅스 시스템이 어떤 조건에 따라 발생시키는 사건이
다.(event)
◦ Signal을 이용해서 프로세스를 관리한다.
◦ 많은 함수와 플래그 값이 있지만 나중에 사용시 레퍼런스 하는 것이 좋을
거라 생각됨.
◦ 몇 가지 예만 설명하고 다음 장으로.
 Signal
◦ 헤더 파일은 <signal.h>
◦ Signal함수, sigaction 함수가 있는데 둘 중 sigaction 함수가 더 효율성
이 좋음.(안정성, 신회성이 더 좋음. )
◦ 자주 쓰이는 신호
 SIGALRM – alarm 함수로 설정된 타이머에 의해 발생
 SIGHUP – 연결 끊긴 터미널이 제어 프로세스에게 보냄
 SIGINT – ctrl + c 또는 그에 해당하는 가로채기 문자가 입력 됬을 때
 SIGKILL – 프로세스를 강제 종료하고자 할 때.
 SIGPIPE – 연관된 판독자가 없는 파이프에 쓰기 시도 시 발생.
 SIGTERM – kill명령이 보내는 기본 신호
 SIGUSR1, SIGUSER2 – 프로세스들이 서로 소통하는 데 쓰임
 SIGCONT – 실행 재개
 SIGCHLD – 자식 프로세스의 중지, 종료 시 발생.
 쓰레드란?
◦ 한 프로그램의 여러 개의 실행 가닥들을 가리켜 쓰레드(thread)라고 부른다.
◦ 좀 더 정확하게 말하자면 쓰레드란, 프로세스 안의 하나의 제어 흐름을 의미한다.
◦ 쓰레드의 장,단점
 장점:
 -자료처리량의 증대, 여러 가지 일의 동시 처리를 통해 효율성증가
 -성능 향상
 -자원의 효율성 증가.
 단점:
 -다중 쓰레드 프로그램의 구현이 난이도가 높음
 -디버깅이 어렵다.
 -다중처리 지원하는 다중 코어 컴퓨터이어야 함.
 다중 쓰레드 프로그램의 예) 문서를 편집하는 동안 실시간으로 문자 수 세는 것.
 첫 번째 다중 쓰레드 프로그램
 쓰레드가 실행할 함수
 -pthread_create의 요구에 따라, 이 함수는 void 포인터 하나를 받고 void
포인터를 돌려준다.
 헤더파일 <pthread.h>
 Int pthread_create(pthread_t* thread, pthread_attr_t* attr, void
*(*start_routine)(void*), void* arg);
1.pthread_t 를 가리키는 포인터, 2. 쓰레드의 특성,
3. Void를 가리키는 포인터를 받고 void를 가리키는 포인터를 돌려주는 함수의 주소 지정
 Main 함수
Res!=0 일 때는 thread가 생성이 실패한 것 = exit, 성공 시 다음 printf를 실행.
Res ==0 일 경우 res = pthread_join(a_thread, &thread_result); 실행.
 동기화
 두 쓰레드 이상이 동시에 실행될 때, 쓰레드 실행을 제어하고 코드의 임계영역에 접
근하기 위한, 즉 좀 더 나은 쓰레드 실행을 제어, 코드의 임계영역에 접근하기 위한,
즉 좀 더 나은 쓰레드 실행 동기화를 위한 일단의 함수들이 존재한다.
 -세마포어(Semaphore) : 코드영역 전후의 관문 역할을 한다.
 -뮤텍스(Mutex) : 코드영역을 보호하기 위한 상호 배제 수단(Mutual exclusion)으로
쓰임.
 ※세마포어는 여러 개의 쓰레드를 동기화 할 때 사용하기 좋으며, 뮤텍스는 하나 하나
의 동기화를 할 때 좋다.
 간단한 예제
 쓰레드가 실행할 함수부분.
 글자 수를 세서 출력하는 함수.
 세마포어를 기다린 후 입력된 문자들의 개수를 셈.
세마포어 초기화.(0으로)
 End 문자 입력 시 종료, FAST입력 시 Wheee… 출력.
End 입력 시 쓰레드 종료, 세마포어 해제. 종료.
 실행화면.
 뮤텍스(Mutex)를 이용한 동기화
 뮤텍스(Mutex)는 일정한 코드 영역이 한 번에 하나의 스레드에 의해서만 실행될 수
있도록 그 영역을 “잠그는” 역할을 한다.(코드 영역 == 임계영역)
 해당영역의 동시접근을 막는다.
 #include <pthread.h>
Int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t*
Mutexattr); - 뮤텍스의 초기화
Int pthread_mutex_lock(pthread_mutex_t* mutex); - 뮤텍스 잠금
Int pthread_mutex_unlock(pthread_mutex_t* mutex); - 뮤텍스 해제
Int pthread_mutex_destroy(pthread_mutex_t* mutex); - 뮤텍스 삭제
*동기화에 대한 부분은 세마포어와 뮤텍스를 통한 기법이 있다 정도만 있으면 된다.
*차후에 프로그래밍 시 적용할 때는 각 함수를 레퍼런스하여 사용.
 쓰레드의 특성
 쓰레드의 특성(attribute)
◦ 가장 중요한 함수는 쓰레드 특성 객체를 초기화하는 pthread_attr_init 이다.
이 함수는 성공 시 0을, 실패 시 -1을 반환한다.
 쓰레드의 특성들
◦ Detachedstate : 이 특성은 쓰레드의 재결합 가능 여부를 결정한다.
◦ Schedpolicy : 쓰레드의 일정 관리 방식을 결정한다.(scheduling)
◦ Schedparam : schedpolicy 에 추가적인 정보를 제공한다.
◦ Inheritsched : 쓰레드의 스케줄링 방식에 대해 설명한다.(해당특성 or 쓰레드를 만든 쓰레드의 방식)
◦ Scope : 쓰레드의 스케줄링을 계산하는 방식을 결정.(리눅스는 PTHREAD_SCOPE_SYSTEM만 지원)
◦ Stacksize : 쓰레드 생성 스택 크기 결정.
 쓰레드의 취소
◦ 한 프로세스가 다른 프로세스에게 신호를 보내서 종료를 요청하듯, 한 쓰레드가 다른 쓰레드에
게 실행종료를 요청해야 하는 경우가 있다. 이 때 쓰이는 함수는
int pthread_cancel(pthread_t thread); // 유일한 인수는 쓰레드의 식별자이다.
그전에 취소 상태를 결정해야 하는데 그 함수는
Int pthread_setcancelstate(int state, int* oldstate);
*자세한 상항은 따로 참조해서 보는것이 좋다.
 두 개 이상의 쓰레드
 여러 개의 새 쓰레드들을 생성해서 동시에 실행하는 예
이 프로그램을 실행시키면 나오는 화면은…
 실행화면
*책에서는 ‘sleep함수를 없애고 해보면
일부 쓰레드들이 같은 인수들로 시작되는
이상한 현상이 빚어진다’ 나온다.
이에 대한 문제는 쓰레드가 빠르게 실행되는 경우
일부 쓰레드는 새로이 갱신된 지역변수의 값을 받게
되고, 그래서 같은 번호를 가진 쓰레드가 생기는 것.
->주소 값으로 받지말고 변수의 값을 스레드 함수에
전달해야 한다.
 요약
◦ 이번장에서만 요약을 쓰는 이유는 그만큼 쓰레드가 중요해서이다.
◦ 쓰레드는 프로세스의 단점을 보완해줄 수 있으며, 여러방면에서 유용하다. 하지만 구현이
어렵다는게 단점이며, 멀티 프로세스에서의 문제점인 동시 실행 문제나 동시 접근의 문제를 가지
고 있다.
윈도우즈 시스템 프로그래밍에서와 비슷하지만 함수관련하여 변수나 다른 부분만 다르지
개념은 같다.
책에서의 설명은,
한 프로세스 안에서 여러 개의 쓰레드들을 생성하는 방법에 대해서 살펴 보았고, 그러한 쓰레드
들은 파일 범위 변수들을 함께 공유한다. 또 그 공유하는 부분에 대해서 세마포와 뮤텍스를 이
용, 임계영역이나 자료에 대한 쓰레드의 접근을 제어하는 것도 보았다.
 IPC : InterProcesscommunication로 프로세스간 통신
을 의미하며 그 중 파이프가 있다.
 파이프(Pipe) : 두 프로세스 사이의 자료 흐름 통로를 제공 하는 수단.
일반적으로 파이프는 한 프로세스의 출력을 다른 프로세스의 입력에
연결하는 용도로 쓰인다.
-popen, pclose – 두 프로그램이 자료를 주고 받는 가장 간단한 방법의 함수.
-pipe 함수 : 위의 popen, pclose 보다 저수준의 함수로 pipe를 사용 시
fread 나 fwrite 같은 함수들이 아니라 read, write 같은 저수준 시스템 호
출들을 사용해야 한다.
*pipe는 나중에… 중요도가 크지 않으므로…
 명명된 파이프 :FIFO
◦ Named pipe(명명된 파이프, 이름있는 파이프)
◦ 자식프로세스와 부모프로세스 관계의 파일, 데이터 주고 받는 것과 달리, 서로 연관되지 않은
프로세스들끼리 자료를 주고 받을 수 있게 하는 파이프
책에서 서버 & 클라이언트와의 연결을 FIFO로 구현하였으며
데이터베이스와의 연결 또한 FIFO로 구현했는데 후에 소켓으로 구현하는
방법이 많이 사용되니 후에 소켓을 자세히 공부하기로 했다.
 세마포(semaphore)란?
◦ 하나의 자원에 단 하나의 프로세스(또는 프로세스)만이 접근함을 보장해야 하는
코드 영역이 있는데, 그런 영역을 임계 영역(critical section)이라고 부른다.
여러 프로그램들이 하나의 공유 자원에 동시에 접근할 때 발생하는 문제를 방지하
려면 한 번에 단 하나의 실행 쓰레드만 하나의 임계영역에 접근할 수 있도록 일종
의 토큰을 생성, 부여하는 수단이 필요하다.
세마포를 이용, 임계 영역에 접근하는 것을 통제, 동기화 한다.
세마포는 오직 대기(wait), 신호(signal) 라는 두 가지 연산만이 가능한 특별한 변
수라고 할 수 있다.
ex) 가장 간단한 세마포는 이진 세마포인데 0, 1 값 만을 가진다.
 세마포의 사용
◦ 책에서는 semaphore_p, semaphore_v 함수를 만들어서,
semaphore_p는 세마포 값을 -1 만큼 변경하게 하며(대기)
semaphore_v는 세마포 값을 +1 만큼 변경하게 하여(신호)
임계영역에 들어갈 때는 semaphore_p를, 나올 때는 semaphore_v를
호출하여 임계 영역에 대한 접근을 동기화한다.
이 함수들은 좀 더 일반적인 semop 함수를 단순화한 인터페이스다.
세마포를 사용한 후에는 삭제하는 것이 좋은데, 프로그램을 다음에 다시
실행할 때 문제가 생길 수 있기 때문이다.
 공유 메모리(Shared Memory)
◦ IPC 수단이며, 서로 무관한 두 프로세스가 동일한 논리적 메모리 영역에
접근할 수 있게 한다. 공유 메모리를 이용하면 실행 중인 두 프로세스가
자료를 아주 효율적인 방식으로 주고받을 수 있다.
IPC가 한 프로세스를 위해 생성한 공유 메모리는 그 프로세스의 주소 공간에서 특
정 범위를 차지한다.
공유 메모리는 여러 프로세스들이 자료를 공유하고 주고받는 효율적인 수단이 된
다. 이 때, 공유 메모리 자체는 동기화 수단을 제공하지 않아서 해당 프로그램이 책
임져야 한다.
*함수)
-shmget : 공유 메모리 생성 /변수 : (key_t key,size_t size,int shmflg)
-shmat : 프로세스의 주소공간에 부착
-shmdt : 공유 메모리를 현재 프로세스에서 떼어낸다.(detach)
-shmctl : 공유 메모리를 제어하는 용도(공유메모리 식별자, 명령, 공유메모리의 모
드들과 권한들을 담은 구조체 포인터)
 메시지 큐(Message queue)
◦ IPC의 한 방법으로 명명된 파이프와 여러모로 비슷한 반면, 파이프를 열고 닫는 데
관련된 번잡함이 없다. 그러나 꽉 찬 파이프에 의한 실행 차단 등 명명된 파이프에
서 발생할 수 있는 문제들은 메시지 큐에도 여전히 존재한다.
메시지 큐를 이용하면 서로 무관한 두 프로세스가 자료를 상당히 쉽고 효율적으로
주고 받을 수 있다. 명명된 파이프와 달리 메시지 큐는 전송 프로세스와 수신 프로
세스 모두에 독립적으로 존재한다. 이 덕분에 파이프에서 열기와 닫기를 동기화할
때 생기는 어려움을 피할 수 있다.
-한 프로세스가 다른 프로세스에게 자료 블록을 전달하는 수단.
각 자료 블록이 자신의 종류를 구분하는 값을 가지고 있어서 수신 프로세스는 서로
다른 종류의 자료 블록들을 독립적으로 받을 수 있고, 처리가 복잡해질 수 있다.
또 파이프와 마찬가지로 각 자료 블록의 크기에는 상한이 존재하며, 시스템 전반의
모든 대기열에 담을 수 있는 블록들의 전체 크기에도 상한이 존재한다.
 메시지 큐 함수
◦ #include <sys/msg.h>
int msgctl(int msgid, int cmd, struct msgid_ds* buf);
int msgget(key_t key, int msgflg);
int msgrcv(int msgid, void* msg_ptr, size_t msg_sz, long int msgtype, int msgflg);
int msgsnd(int msgid, const void* msg_ptr, size_t msg_sz, int msgflg);
<함수>
Msgget : 메시지 큐에 접근할 때 사용하는 함수.
Msgsnd : 메시지 큐에 하나의 메시지를 전송할 때 사용하는 함수.
Msgrcv : 메시지 큐에서 메시지를 받을 때 사용하는 함수.
Smgctl : 메시지 큐를 제어하는 함수.
(공유 메모리의 제어 함수와 아주 비슷)
 각각의 IPC 상태보는 명령어(터미널 창에서)
◦ 세마포 상태 보기
 ipcs –s
◦ 공유 메모리 상태 보기
 ipcs –m
◦ 메시지 큐 상태 보기
 ipcs -q
 소켓이란..?
◦ Ch13, 14장에서 다루었던 것과 근본적인 차이를 보인다. 소켓에
서는 여러 컴퓨터들의 경계를 넘나들 수 있다.
소켓의 사용 방법은 파이프 사용 방법과 매우 비슷하지만, 여러 컴
퓨터들의 네트워크를 가로질러서 자료를 주고받을 수 있는 능력
은 소켓에만 해당된다. 한 컴퓨터의 프로세스는 소켓을 통해서 다
른 컴퓨터의 프로세스와 통신할 수 있으며, 이를 통해서 네트워크
상에 분산된 클라이언트/서버 시스템을 구축할 수 있다.
ex) 원격 인쇄, 데이터베이스 연결, 웹 서버 기능 등.
◦ *소켓 인터페이스는 Windows도 지원하며, 윈속(WinSock)이라고
부른다.
 주제
◦ 소켓 연결의 작동 방식
◦ 소켓의 특성들과 주소, 통신
◦ 네트워크 정보와 인터넷 데몬
◦ 클라이언트와 서버
 소켓 연결
◦ 1. 서버 응용프로그램이 소켓을 생성한다. 서버는 시스템 호출 socket을 이용, 소
켓을 생성.(이 소켓은 다른 프로세스와 공유되지 못한다.
◦ 2.서버 프로세스는 그 소켓에 하나의 이름을 부여한다. 네트워크 소켓의 경우 클라
이언트가 연결할 수 있는 특정 네트워크에 관련된 서비스 식별자가 부여된다.
소켓에 이름을 부여할 때 사용하는 시스템 호출은 bind 이다. 이름을 부여한 후,
서버 프로세스는 해당 소켓에 클라이언트가 연결되기를 기다린다. 이를 위한 시스
템 호출은 listen이며, 이 함수는 들어오는 연결을 위한 대기열을 생성한다. 연결
요청이 들어오면 서버는 시스템 호출 accept를 이용해서 그 요청을 받아들인다.
서버가 accept를 호출하면, 명명된 소켓과는 개별적인 새로운 소켓이 생성된다.
이 새 소켓은 해당 클라이언트 하나와의 통신에만 쓰인다.
-클라이언트 쪽의 소켓 기반 시스템은 훨씬 간단하다. 클라이언트는 socket을
호출해서 이름없는 소켓을 생성, 그 다음에는 서버의 명명된 소켓을 주소로
사용해 connect를 호출함으로써 서버와의 연결을 만든다.
 소켓 특성들.
◦ 소켓을 규정하는 가장 중요한 특성 세 가지는 도메인, 종류, 프로토콜 이다.
◦ 소켓은 또한 주소로 쓰이는 이름도 가지는데, 주소의 형식은 도메인에 따라 다르다.
◦ 도메인을 프로토콜 패밀리라고 부르기도 한다.
◦ 소켓 도메인.
 도메인은 소켓 통신이 사용할 네트워크 매체를 결정한다. 가장 흔히 쓰이는 소켓 도메인은
AF_INET으로, 이것은 인터넷 자체는 물론 여러 리눅스 근거리 통신망에도 쓰이는 인터넷
네트워킹에 해당한다. 이 도메인의 프로토콜 패밀리는 인터넷 프로토콜(IP)이다.
인터넷 프로토콜에서 네트워크상의 특정한 컴퓨터를 지칭하는 데 쓰이는 주소 형식은
IP주소 하나뿐이다
 소켓의 종류
◦ 스트림 소켓
 표준 입, 출력 스트림과 다소 비슷한 면을 가진 스트림 소켓은 순차적인, 그리고 신뢰성 있
는 양방향 바이트 스트림 방식의 연결을 제공한다.(신뢰성 : 전송된 자료가 오류가 보고되지
않고 소실되거나, 복제되거나, 순서가 바뀌는 일은 없다는 뜻)
◦ 데이터그램 소켓
 연결의 유지 및 관리를 수행하지 않는다. 또한 이 종류의 소켓에서 보낼 수 있는 하나의 데
이터그램의 크기에는 한계가 주어져 있다. 데이터그램은 도중에 소실되거나, 중복되거나,
다른 데이터그램과 순서가 바뀔 수 있다. (UDP/IP 연결을 통해 구현된다.)
 순차성과 신뢰성을 보장하진 않지만, 네트워크 연결을 유지할 필요가 없기 때문에 자원 효
율성이 좋다. 연결 설정하는데 소요 시간이 없기 때문에 속도도 빠르다.
◦ 소켓 프로토콜
 소켓 종류의 전송 메커니즘이 여러 개의 프로토콜들을 제공하는 경우 프로그램은 그 중 하
나를 선택할 수 있다. 책에서는 다른 소켓 프로토콜은 사용하지 않았다.
 소켓 생성
◦ int socket(int domain, int type, int protocol);
 domain 은 소켓의 주소 패밀리를 결정
 type 는 소켓에 쓰일 통신의 종류를 결정.
 protocol은 그 통신을 위한 프로토콜을 결정.
 Socket 시스템 호출은 하나의 서술자를 돌려주는데, 이것은 저수준 파
일 시스템 서술자와 여러모로 비슷하다.
 소켓이 연결되면 이 서술자로 시스템 호출 read, write를 호출, 자료를
읽거나 쓸 수 있다. 소켓 연결을 끝낼 때에는 close 사용.
 소켓 이름 붙이기
◦ int bind(int socket, const struct sockaddr* address,
size_t address_len);
 Bind 시스템 호출은 socket 변수로 지정된 이름 없는 소켓에 address 매개변수
로 지정된 주소 구조체에 담긴 주소를 부여한다.
 Bind를 호출할 때에는 특정 주소 구조체 포인터를 반드시 일반적인 주소 형식
포인터(struct sockaddr*)로 강제 형변환해야 한다.
 bind는 성공 시 0을, 실패 시 -1을 반환.
 소켓 연결 대기열 만들기
◦ int listen(int socket, int backlog);
 backlog 변수는 listen이 생성할 대기열의 크기, 즉 대기열에 담을 수 있는 연
결 요청들의 최대 개수이다.
 listen함수는 성공 시 0을, 실패 시 -1을 돌려준다.
 연결 수락
◦ Int accept(int socket, struct sockaddr* address,
size_t* address_len);
Accept 시스템 호출은 socket 변수로 지정된 소켓에 클라이언트가 연결을 시도하길
기다린다. 그 클라이언트는 소켓의 대기열의 첫 번째 연결 요청에 해당한다.
accept는 그 클라이언트의 통신을 위한 새 소켓을 생성한 후 그것의 서술자를 반환
한다. 새 소켓은 서버의 청취 소켓과 같은 종류이다.
- socket 변수에는 반드시 bind로 명명, listen으로 대기열을 만든 소켓의 서술자를
지정해야 한다.
-address 변수가 가리키는 곳에는 연결된 클라이언트의 주소 구조체가 설정된다.
-address_len 변수에는 클라이언트 주소 구조체의 길이를 담은 변수의 주소 설정.
*소켓의 대기열에 연결 요청이 하나도 없으면 accept 호출이 차단되며, 클라이언트
가 연결을 요청하면 비로소 서버 프로세스의 실행이 재개된다
 연결 요청
◦ int connect(int socket, const struct sockaddr* address,
size_t address_len);
 Socket 변수는 클라이언트쪽 소켓의 서술자이고 address는 서버쪽 소켓의 주
소를 담은 구조체를 가리킨다.
 Address_len은 그 구조체의 길이이다.
 Socket변수에는 반드시 socket 호출로 얻은 유효한 서술자를 지정해야한다.
 connect는 성공시 0, 실패시 -1을 돌려준다.
 소켓 닫기
◦ Close를 호출해서 소켓연결을 끝낼 수 있다.
 다중 클라이언트
◦ 하나의 서버에 여러 개의 클라이언트들이 동시에 연결하
는 경우.
 서버 프로그램 측에서 fork를 이용, 다중 클라이언트를 처리할 수도 있
으며 select 함수를 이용하여 처리 할 수도 있다.
 여기서 select란, 시스템 호출로써 저수준 파일 서술자들을 하나의 단
위로 취급해서 그것들 중 하나에 입력이 들어오기를(또는 출력이 완료
되길) 기다릴 수 있다. 만약 다중 클라이언트에서 사용한다면, 서버 쪽
청취 소켓과 클라이언트 연결 소켓 모두를 동시에 기다린다. 둘 중 하
나라도 활동이 감지되면, 모든 가능한 파일 서술자를 점검, 어떤 소켓
이 깨어났는지 파악, 그에 따라 적절한 처리를 수행한다.
 서버 쪽 청취 소켓에 입력이 들어왔다면 어떤 클라이언트가 서버와의
연결을 시도한 것이다. 이 경우 차단을 걱정하지 않고 accept를 호출
할 수 있다.
 간단한 실습 (client 쪽, client1.c)
그냥 client1만 실행시키면,
Server와 같이 실행시키면
 간단한 실습(server1.c 서버 쪽)
./server1 & 을 입력, server1을
백그라운드 작업하여 client1을
실행시키는데,
./server1 & 후 ps 의 상태는,
그리고 서버는 파일 시스템상의 소켓을
생성하는데 그 파일은 ls 명령으로 볼 수 있다
다 사용한 소켓은 제거하는 것이 좋다.
(프로그램이 신호에 의해서 비정상적으로
종료되었다면, 소켓이 남아 있는지 확인,
제거해야 파일 시스템이 지저분해지는 것을
피할 수 있다.
 간단한 실습에 대한…
◦ 서버는 클라이언트가 기록한 문자 하나를 읽어서 그것을 증가한 후
다시 클라이언트에게 보낸다.(출력하는 건 클라이언트 측)
더 상세히 공부하고 싶었지만 처음 책을 정독한것에
대해 만족을 하며, 프로그래밍을 할 때, 다시 책을
볼 때, 좀 더 코드 부분과 직접 프로그래밍하는거
에 중점을 둘 필요가 있다고 생각이 드는 공부였다.
그리고 중요하다고 생각되는 부분만 공부하였는데
차후에 공부할 때에는 다른 부분도 공부를 해야겠
다. 또 소켓 프로그래밍 같은 부분은 따로 책이 있
으니 그 부분에 대해서 더 공부할 필요성이 느껴진
다.
Linux programming study

Contenu connexe

Tendances

10장 문자열클래스와파일클래스
10장 문자열클래스와파일클래스10장 문자열클래스와파일클래스
10장 문자열클래스와파일클래스
웅식 전
 
10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스
유석 남
 
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6
SukYun Yoon
 

Tendances (20)

Free rtos seminar
Free rtos seminarFree rtos seminar
Free rtos seminar
 
System+os study 3
System+os study 3System+os study 3
System+os study 3
 
[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것
[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것
[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것
 
System+os study 5
System+os study 5System+os study 5
System+os study 5
 
[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리
 
Tcpdump
TcpdumpTcpdump
Tcpdump
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3
 
10장 문자열클래스와파일클래스
10장 문자열클래스와파일클래스10장 문자열클래스와파일클래스
10장 문자열클래스와파일클래스
 
Linux reversing study_basic_4
Linux reversing study_basic_4Linux reversing study_basic_4
Linux reversing study_basic_4
 
10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 
Windows reversing study_basic_9
Windows reversing study_basic_9Windows reversing study_basic_9
Windows reversing study_basic_9
 
Python
PythonPython
Python
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1
 
200523 서울여대 BI 코딩실무 강의 자료
200523 서울여대 BI 코딩실무 강의 자료200523 서울여대 BI 코딩실무 강의 자료
200523 서울여대 BI 코딩실무 강의 자료
 
Pwnable study basic_1
Pwnable study basic_1Pwnable study basic_1
Pwnable study basic_1
 
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6
 
[강릉원주대 대기환경과학과] 대기과학전산입문 설명서
[강릉원주대 대기환경과학과] 대기과학전산입문 설명서[강릉원주대 대기환경과학과] 대기과학전산입문 설명서
[강릉원주대 대기환경과학과] 대기과학전산입문 설명서
 
20160427 ROS 4차 강의 (for 아스라다 팀)
20160427 ROS 4차 강의 (for 아스라다 팀)20160427 ROS 4차 강의 (for 아스라다 팀)
20160427 ROS 4차 강의 (for 아스라다 팀)
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2
 

Similaire à Linux programming study

하둡 타입과 포맷
하둡 타입과 포맷하둡 타입과 포맷
하둡 타입과 포맷
진호 박
 

Similaire à Linux programming study (20)

shell and process
shell and processshell and process
shell and process
 
Network researching
Network researchingNetwork researching
Network researching
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
 
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
실무로 배우는 시스템 성능 최적화 8부 - 1,2,3장
 
Linux 강의자료 ed10
Linux 강의자료 ed10Linux 강의자료 ed10
Linux 강의자료 ed10
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
 
IoT with Raspberry Pi + Node JS - Chapter 1
IoT with Raspberry Pi + Node JS - Chapter 1IoT with Raspberry Pi + Node JS - Chapter 1
IoT with Raspberry Pi + Node JS - Chapter 1
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
Hyperledger farbric build your first network install and analysis
Hyperledger farbric   build your first network install and analysisHyperledger farbric   build your first network install and analysis
Hyperledger farbric build your first network install and analysis
 
20150509 unix v6로 배우는 커널의 원리와 구조 4 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 4 김지은20150509 unix v6로 배우는 커널의 원리와 구조 4 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 4 김지은
 
UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제UNIX 시스템 2014-2018년 기말시험 기출문제
UNIX 시스템 2014-2018년 기말시험 기출문제
 
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdfOS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
 
Thread programming
Thread programmingThread programming
Thread programming
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6
 
고급시스템프로그래밍
고급시스템프로그래밍고급시스템프로그래밍
고급시스템프로그래밍
 
Nodejs_chapter3
Nodejs_chapter3Nodejs_chapter3
Nodejs_chapter3
 
Buffer Overflow PPT (OneTwo)
Buffer Overflow PPT (OneTwo)Buffer Overflow PPT (OneTwo)
Buffer Overflow PPT (OneTwo)
 
하둡 타입과 포맷
하둡 타입과 포맷하둡 타입과 포맷
하둡 타입과 포맷
 
[IoT] MAKE with Open H/W + Node.JS - 2nd
[IoT] MAKE with Open H/W + Node.JS - 2nd[IoT] MAKE with Open H/W + Node.JS - 2nd
[IoT] MAKE with Open H/W + Node.JS - 2nd
 
linux1
linux1linux1
linux1
 

Linux programming study

  • 2.  주요 챕터  각각의 챕터에 대한 이론  코드 및 설명  공부하면서 배운 것, 느낀점.
  • 3.  Ch3. 파일 다루기  Ch11.프로세스와 신호  Ch12.쓰레드  Ch13.프로세스간 통신 : 파이프  Ch14. 세마포, 공유 메모리, 메시지 큐  Ch15. 소켓
  • 4.  파일과 디렉토리를 다루는 여러 가지 함수들을 상 세히 설명하는 데 주력. ◦ 파일과 장치 ◦ 시스템 호출 ◦ 라이브러리 함수 ◦ 파일 다루기 ◦ 표준 I/O 라이브러리 ◦ 입,출력 서식화 ◦ 파일과 디렉터리 관리 ◦ 디렉터리 탐색 ◦ 오류처리, /proc 파일 시스템, fcntl과 mmap
  • 5.  저수준 파일 접근 하나의 프로그램이 시동될 때에는 일반적으로 세 개의 파일 서술자들이 이미 열린 상태이다. - 0 : 표준 입력 - 1 : 표준 출력 - 2 : 표준 오류 위의 파일 서술자는 자동으로 열리며, 따라서 프로그램은 별다른 절차 없이 Write를 이용, 즉시 해당 장치에 자료를 기록할 수 있다.
  • 6.  Write Write 시스템 호출은 버퍼 buf에 있는 처음 nbytes 개의 바이트들을 파일 서술자 fildes에 연관된 파일에 기록하고, 실제로 기록한 바이트 수를 돌 려준다. 시스템 호출의 구문 #include <unistd.h> Size_t write(int fildes, const void* buf, size_t nbytes);
  • 7.  Read Read 시스템 호출은 파일 서술자 fildes에 연관된 파일로부터 nbytes개의 바 이트들을 읽어서 그 바이트들을 버퍼 buf에 집어넣는다. 반환값은 실제로 읽은 바이트 개수인데, 요청한 바이트 수보다 작을 수도 있다. 반환값이 0이면 아무 것도 읽지 않은 것이다(파일의 끝에 도달한 경우). -1 은 오류를 의미 #include <unistd.h> Size_t read(int fildes, void *buf,size_t nbytes);
  • 8.  Open 새 파일 서술자를 만들기 위해서는 open 시스템 호출을 사용해야 한다. #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> Int open(const char* path, int oflags); Int open(const char* path, int oflags, mode_t mode); 간단히 말하자면 open은 파일 또는 장치로의 접근 경로를 만듬. Flag값을 통해 모드 설정, O_RDONLY, O_WRONLY, O_RDWR 각각 읽기, 쓰기, 읽기 쓰기 가능하게 하는 모드. (이들 중 하나를 반드시 지정해야 한다.) (다른 플래그 값이 있지만 상세한 부분은 생략한다.)
  • 9.  초기 권한 그림에서 보듯이, drwxrwxr-x :디렉토리, 사용자,그룹,다른 사용자 R은 읽기권한, w는 쓰기, x는 실행 이다. 이 후에 close 함수, ioctl 함수가 있는데 close는 파일 서술자와 파일의 연관 을 끊는 함수, ioctl함수는 파일 서술자(fildes)가 가리키는 대상에 대해 cmd로 지정된 기능을 수행한다.
  • 10.  나머지 파일 관리 관련 시스템 호출들 -lseek : 파일 서술자(fildes)가 가리키는 파일의 읽기/쓰기 포인터 설정한다. -fstat,stat,lstat : 파일서술자에 연관된 파일의 상태 정보를 돌려준다. -dup, dup2 : 파일 서술자를 복제하는 데 쓰인다. 이 호출들에 대한 변수나 자세한 사항은 참조하여 사용한다.
  • 11.  표준 I/O 라이브러리 ->표준 I/O 라이브러리와 해당 헤더 파일은 저수준 I/O 시스템 호출들에 대한 융통성 있는 인터페이스를 제공한다. 아래에 설명할 부분은 저수준 시스템 호출이다. -fopen : 이 함수는 주로 파일과 터미널의 입.출력에 쓰인다. 장치들을 좀 더 명시적으 로 제어하려면 저수준 시스템 호출을 사용하는 것이 좋다. -fread : 파일 스트림으로부터 자료를 읽는데 쓰인다. 읽은 자료는 ptr이 가리키는 자료 버퍼에 기록된다.fread, fwrite 모두 자료를 레코드 단위로 처리한다. -fclose : 스트림 매개변수로 지정된 스트림을 닫는다. 이때 아직 기록되지 않은 자료가 모두 기록된다.명시적으로 사용해주면 좋다. -fwrite : 인터페이스는 fread와 비슷하다. 출력 스트림에 기록, 성공적으로 기록한 레코 드 개수를 돌려준다. -fflush : 주어진 파일 스트림에 대해 대기 중인 모든 자료를 즉시 기록한다. 예) 대화식 프롬프트가 확실히 터미널에 출력된 후에만 사용자의 입력을 받아 들여야하 는 경우에 유용.fclose 호출하는 시점에서는 fflush를 굳이 호출할 필요가 없다. *헤더파일은 stdio.h 이다.
  • 12.  표준 I/O 라이브러리 -fseek : 시스템 호출 lseek에 해당. 이 함수는 스트림에서 다음번에 자료를 읽거나 쓸 위치를 설정한다. 차이점은 lseek은 off_t, fseek은 성공시 0, 실패시 -1 반환한다. -fget, getc, getchar : 파일 스트림에서 다음 바이트(문자)를 돌려준다. 파일의 끝에 도달했거나 오류가 있다면 EOF를 돌려준다. -fputc, putc, putchar : fputc는 문자 하나를 출력 스트림에 기록한다. 성공 시 문자의 값을 돌려주고, 실패 시 EOF를 돌려준다. -fgets, gets : 입력 파일 스트림에서 하나의 문자열을 읽어 들인다. Ex) char* fgets(char* s, int n, FILE* stream); char* gets(char* s); ->s가 가리키는 문자열에 넣되 새 줄 문자를 만나거나, n-1개의 문자들을 읽었거나, 파 일의 끝에 도달하면 멈춘다. 새 줄 문자도 s에 저장된다. *EOF는 End Of File의 약자
  • 13.  서식화된 입력과 출력 -printf, fprintf, sprintf : 서로 다른 형식의 여러 인수들을 서식화해서 출력한다. -scanf, fscanf, sscanf : 스트림으로부터 값들을 읽고 그것들을 포인터 매개변수들이 가리키는 변수들에 집어넣는다. -기타 다른 함수들도 많지만 (표준 스트림 stdin, stdout,stderr 을 사용하는 함수들) 파일 스트림에 대한 설정이나 위치설정 등이다.
  • 14.  파일과 디렉터리의 생성 및 관리 -파일, 디렉터리의 생성 및 관리를 위한 여러 표준 라이브러리 함수들과 시스템 호출. -chmod : 시스템 호출로, 파일이나 디렉터리의 접근 권한을 변경하는 데 쓰인다. -chown : 슈퍼사용자는 이 시스템 호출로 파일의 소유자를 변경할 수 있다. -unlink : 파일의 제거. -mkdir, rmdir : 디렉토리의 생성, 제거. 권한 설정은 umask에 의존한다. -chdir 와 getcwd : 현재 디렉토리 변경 시 chdir 시스템 호출. 현재 디렉토리를 알고 싶을 때는 getcwd함수 사용. -opendir : 디렉터리를 열고 그에 대한 디렉터리 스트림을 만듬. 성공시 디렉터리 항목 들을 읽는데 사용할 DIR 구조체를 가리키는 포인터를 돌려준다. -readdir : 디렉터리 스트림 안의 다음 디렉터리 항목에 대한 구조체의 포인터를 반환. -telldir : 디렉터리의 스트림의 현재 위치에 해당하는 값을 돌려준다. -seekdir : 주어진 디렉터리 스트림의 현재 디렉터리 항목 위치를 변경한다. -closedir : 디렉터리 스트림을 닫고 그에 연관된 자원들을 해제한다. 성공 시 0 반환.
  • 15.  오류처리 -strerror : 주어진 오류 번호에 해당하는 오류 메시지 문자열을 반환한다. -perror : 오류 번호를 직접 받는 대신 현재 errno에 설정된 값을 사용.  /PROC 파일 시스템 ->이 파일 시스템이 제공하는 것은 드라이버들과 커널 기능.  Fcntl 과 mmap ->fcntl은 저수준 파일 서술자를 통해 파일을 좀 더 세밀하게 제어. ->mmap 둘 이상의 프로그램들이 읽거나 쓸 수 있는 메모리 영역을 설정.
  • 16.  프로세스와 신호에서 다루게 될 부분 ◦ 프로세스 구조, 종류, 일정 ◦ 새 프로세스를 시작하는 여러 가지 방법들 ◦ 부모, 자식, 좀비 프로세스 ◦ 신호와 그 활용 방법  프로세스란…? ◦ “하나 이상의 스레드들과 그 스레드들에 필요한 시스템 자원들을 포함하는 하나의 주소 공간”으로 정의한다. ◦ 프로세스를 현재 실행 중인 하나의 프로그램으로 간주.
  • 17.  프로세스 구조, 종류, 일정(스케줄링) PID 101 CODE 자료 라이브러리 파일들 PID 102 CODE 자료 라이브러리 파일들 code C라이브러리 Treck.txt nene.txt $ grep 자료 treck.txt $ grep 자료 nene.txt
  • 18.  프로세스 보기 프로세스의 상태 현재 실행중인 프로세스
  • 19.  새 프로세스 시작 ◦ System 함수를 이용한 프로세스의 시작. 여기선 clear 명령어를 사용했다.
  • 20.  프로세스 이미지 대체하기 ◦ Exec 함수를 이용, 새 프로세스를 띄우지만 프로세스를 띄우는 방식이나 프로그램 인수들을 제공하는 방식은 서로 다르다.  System 함수보다 훨씬 효율적 -> 새 프로그램이 시작된 후에는 원래의 프로그 램이 더 이상 실행될 필요가 없다는 점에서 system 함수보다 훨씬 효율적.  예) execl(const char* path, const char* arg0, … ,(char*)0); Execlp를 이용한 ps ax 실행.
  • 21.  프로세스의 이미지 복제(fork) ◦ 동시에 여러 기능을 수행하고자 할 때에는 제 12장에서 다루는 스 레드를 사용할 수도 있고, init이 하는 것처럼 한 프로그램 안에서 완전히 개별적인 프로세스를 생성 할 수도 있다. 초기 프로세스 Fork() 원래 프로세스 의 실행 새 프로세스 0을 리턴 새 PID 리턴
  • 22.  Fork함수의 책에서의 간단한 예제 중간에 명령프롬프트가 껴있는데 그 이유는 자식 프로세스는 여전히 실행 중, 부모프로세스는 끝난 이유이다.
  • 23.  좀비 프로세스 ◦ Fork를 이용한 프로세스 생성은 유용하나, 실행이 종료되었으나 부모와 의 연관관계가 아직 남아 있는 프로세스를 가리켜서 소멸된(defunct)프 로세스, 좀비 프로세스라고 부른다. 실행 시 뒤에 & 붙여서 백그라운드 작업 후 부모 프로세스 끝나기 전에 ps 명령어를 실행시켜보면, <defunct> 라고 나오며, 이것이 좀비 프로세스이다.
  • 24.  쓰레드 ◦ 리눅스에서 프로세스보다 작은 실행 단위로 스레드라는 것이 있다. 추후 ch12 에서 다룸.  신호(signal) ◦ 신호는 유닉스와 리눅스 시스템이 어떤 조건에 따라 발생시키는 사건이 다.(event) ◦ Signal을 이용해서 프로세스를 관리한다. ◦ 많은 함수와 플래그 값이 있지만 나중에 사용시 레퍼런스 하는 것이 좋을 거라 생각됨. ◦ 몇 가지 예만 설명하고 다음 장으로.
  • 25.  Signal ◦ 헤더 파일은 <signal.h> ◦ Signal함수, sigaction 함수가 있는데 둘 중 sigaction 함수가 더 효율성 이 좋음.(안정성, 신회성이 더 좋음. ) ◦ 자주 쓰이는 신호  SIGALRM – alarm 함수로 설정된 타이머에 의해 발생  SIGHUP – 연결 끊긴 터미널이 제어 프로세스에게 보냄  SIGINT – ctrl + c 또는 그에 해당하는 가로채기 문자가 입력 됬을 때  SIGKILL – 프로세스를 강제 종료하고자 할 때.  SIGPIPE – 연관된 판독자가 없는 파이프에 쓰기 시도 시 발생.  SIGTERM – kill명령이 보내는 기본 신호  SIGUSR1, SIGUSER2 – 프로세스들이 서로 소통하는 데 쓰임  SIGCONT – 실행 재개  SIGCHLD – 자식 프로세스의 중지, 종료 시 발생.
  • 26.  쓰레드란? ◦ 한 프로그램의 여러 개의 실행 가닥들을 가리켜 쓰레드(thread)라고 부른다. ◦ 좀 더 정확하게 말하자면 쓰레드란, 프로세스 안의 하나의 제어 흐름을 의미한다. ◦ 쓰레드의 장,단점  장점:  -자료처리량의 증대, 여러 가지 일의 동시 처리를 통해 효율성증가  -성능 향상  -자원의 효율성 증가.  단점:  -다중 쓰레드 프로그램의 구현이 난이도가 높음  -디버깅이 어렵다.  -다중처리 지원하는 다중 코어 컴퓨터이어야 함.  다중 쓰레드 프로그램의 예) 문서를 편집하는 동안 실시간으로 문자 수 세는 것.
  • 27.  첫 번째 다중 쓰레드 프로그램
  • 28.  쓰레드가 실행할 함수  -pthread_create의 요구에 따라, 이 함수는 void 포인터 하나를 받고 void 포인터를 돌려준다.  헤더파일 <pthread.h>  Int pthread_create(pthread_t* thread, pthread_attr_t* attr, void *(*start_routine)(void*), void* arg); 1.pthread_t 를 가리키는 포인터, 2. 쓰레드의 특성, 3. Void를 가리키는 포인터를 받고 void를 가리키는 포인터를 돌려주는 함수의 주소 지정
  • 29.  Main 함수 Res!=0 일 때는 thread가 생성이 실패한 것 = exit, 성공 시 다음 printf를 실행. Res ==0 일 경우 res = pthread_join(a_thread, &thread_result); 실행.
  • 30.  동기화  두 쓰레드 이상이 동시에 실행될 때, 쓰레드 실행을 제어하고 코드의 임계영역에 접 근하기 위한, 즉 좀 더 나은 쓰레드 실행을 제어, 코드의 임계영역에 접근하기 위한, 즉 좀 더 나은 쓰레드 실행 동기화를 위한 일단의 함수들이 존재한다.  -세마포어(Semaphore) : 코드영역 전후의 관문 역할을 한다.  -뮤텍스(Mutex) : 코드영역을 보호하기 위한 상호 배제 수단(Mutual exclusion)으로 쓰임.  ※세마포어는 여러 개의 쓰레드를 동기화 할 때 사용하기 좋으며, 뮤텍스는 하나 하나 의 동기화를 할 때 좋다.  간단한 예제
  • 31.  쓰레드가 실행할 함수부분.  글자 수를 세서 출력하는 함수.  세마포어를 기다린 후 입력된 문자들의 개수를 셈. 세마포어 초기화.(0으로)
  • 32.  End 문자 입력 시 종료, FAST입력 시 Wheee… 출력. End 입력 시 쓰레드 종료, 세마포어 해제. 종료.
  • 34.  뮤텍스(Mutex)를 이용한 동기화  뮤텍스(Mutex)는 일정한 코드 영역이 한 번에 하나의 스레드에 의해서만 실행될 수 있도록 그 영역을 “잠그는” 역할을 한다.(코드 영역 == 임계영역)  해당영역의 동시접근을 막는다.  #include <pthread.h> Int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* Mutexattr); - 뮤텍스의 초기화 Int pthread_mutex_lock(pthread_mutex_t* mutex); - 뮤텍스 잠금 Int pthread_mutex_unlock(pthread_mutex_t* mutex); - 뮤텍스 해제 Int pthread_mutex_destroy(pthread_mutex_t* mutex); - 뮤텍스 삭제 *동기화에 대한 부분은 세마포어와 뮤텍스를 통한 기법이 있다 정도만 있으면 된다. *차후에 프로그래밍 시 적용할 때는 각 함수를 레퍼런스하여 사용.
  • 35.  쓰레드의 특성  쓰레드의 특성(attribute) ◦ 가장 중요한 함수는 쓰레드 특성 객체를 초기화하는 pthread_attr_init 이다. 이 함수는 성공 시 0을, 실패 시 -1을 반환한다.  쓰레드의 특성들 ◦ Detachedstate : 이 특성은 쓰레드의 재결합 가능 여부를 결정한다. ◦ Schedpolicy : 쓰레드의 일정 관리 방식을 결정한다.(scheduling) ◦ Schedparam : schedpolicy 에 추가적인 정보를 제공한다. ◦ Inheritsched : 쓰레드의 스케줄링 방식에 대해 설명한다.(해당특성 or 쓰레드를 만든 쓰레드의 방식) ◦ Scope : 쓰레드의 스케줄링을 계산하는 방식을 결정.(리눅스는 PTHREAD_SCOPE_SYSTEM만 지원) ◦ Stacksize : 쓰레드 생성 스택 크기 결정.
  • 36.  쓰레드의 취소 ◦ 한 프로세스가 다른 프로세스에게 신호를 보내서 종료를 요청하듯, 한 쓰레드가 다른 쓰레드에 게 실행종료를 요청해야 하는 경우가 있다. 이 때 쓰이는 함수는 int pthread_cancel(pthread_t thread); // 유일한 인수는 쓰레드의 식별자이다. 그전에 취소 상태를 결정해야 하는데 그 함수는 Int pthread_setcancelstate(int state, int* oldstate); *자세한 상항은 따로 참조해서 보는것이 좋다.
  • 37.  두 개 이상의 쓰레드  여러 개의 새 쓰레드들을 생성해서 동시에 실행하는 예 이 프로그램을 실행시키면 나오는 화면은…
  • 38.  실행화면 *책에서는 ‘sleep함수를 없애고 해보면 일부 쓰레드들이 같은 인수들로 시작되는 이상한 현상이 빚어진다’ 나온다. 이에 대한 문제는 쓰레드가 빠르게 실행되는 경우 일부 쓰레드는 새로이 갱신된 지역변수의 값을 받게 되고, 그래서 같은 번호를 가진 쓰레드가 생기는 것. ->주소 값으로 받지말고 변수의 값을 스레드 함수에 전달해야 한다.
  • 39.  요약 ◦ 이번장에서만 요약을 쓰는 이유는 그만큼 쓰레드가 중요해서이다. ◦ 쓰레드는 프로세스의 단점을 보완해줄 수 있으며, 여러방면에서 유용하다. 하지만 구현이 어렵다는게 단점이며, 멀티 프로세스에서의 문제점인 동시 실행 문제나 동시 접근의 문제를 가지 고 있다. 윈도우즈 시스템 프로그래밍에서와 비슷하지만 함수관련하여 변수나 다른 부분만 다르지 개념은 같다. 책에서의 설명은, 한 프로세스 안에서 여러 개의 쓰레드들을 생성하는 방법에 대해서 살펴 보았고, 그러한 쓰레드 들은 파일 범위 변수들을 함께 공유한다. 또 그 공유하는 부분에 대해서 세마포와 뮤텍스를 이 용, 임계영역이나 자료에 대한 쓰레드의 접근을 제어하는 것도 보았다.
  • 40.  IPC : InterProcesscommunication로 프로세스간 통신 을 의미하며 그 중 파이프가 있다.  파이프(Pipe) : 두 프로세스 사이의 자료 흐름 통로를 제공 하는 수단. 일반적으로 파이프는 한 프로세스의 출력을 다른 프로세스의 입력에 연결하는 용도로 쓰인다. -popen, pclose – 두 프로그램이 자료를 주고 받는 가장 간단한 방법의 함수. -pipe 함수 : 위의 popen, pclose 보다 저수준의 함수로 pipe를 사용 시 fread 나 fwrite 같은 함수들이 아니라 read, write 같은 저수준 시스템 호 출들을 사용해야 한다. *pipe는 나중에… 중요도가 크지 않으므로…
  • 41.  명명된 파이프 :FIFO ◦ Named pipe(명명된 파이프, 이름있는 파이프) ◦ 자식프로세스와 부모프로세스 관계의 파일, 데이터 주고 받는 것과 달리, 서로 연관되지 않은 프로세스들끼리 자료를 주고 받을 수 있게 하는 파이프 책에서 서버 & 클라이언트와의 연결을 FIFO로 구현하였으며 데이터베이스와의 연결 또한 FIFO로 구현했는데 후에 소켓으로 구현하는 방법이 많이 사용되니 후에 소켓을 자세히 공부하기로 했다.
  • 42.  세마포(semaphore)란? ◦ 하나의 자원에 단 하나의 프로세스(또는 프로세스)만이 접근함을 보장해야 하는 코드 영역이 있는데, 그런 영역을 임계 영역(critical section)이라고 부른다. 여러 프로그램들이 하나의 공유 자원에 동시에 접근할 때 발생하는 문제를 방지하 려면 한 번에 단 하나의 실행 쓰레드만 하나의 임계영역에 접근할 수 있도록 일종 의 토큰을 생성, 부여하는 수단이 필요하다. 세마포를 이용, 임계 영역에 접근하는 것을 통제, 동기화 한다. 세마포는 오직 대기(wait), 신호(signal) 라는 두 가지 연산만이 가능한 특별한 변 수라고 할 수 있다. ex) 가장 간단한 세마포는 이진 세마포인데 0, 1 값 만을 가진다.
  • 43.  세마포의 사용 ◦ 책에서는 semaphore_p, semaphore_v 함수를 만들어서, semaphore_p는 세마포 값을 -1 만큼 변경하게 하며(대기) semaphore_v는 세마포 값을 +1 만큼 변경하게 하여(신호) 임계영역에 들어갈 때는 semaphore_p를, 나올 때는 semaphore_v를 호출하여 임계 영역에 대한 접근을 동기화한다. 이 함수들은 좀 더 일반적인 semop 함수를 단순화한 인터페이스다. 세마포를 사용한 후에는 삭제하는 것이 좋은데, 프로그램을 다음에 다시 실행할 때 문제가 생길 수 있기 때문이다.
  • 44.  공유 메모리(Shared Memory) ◦ IPC 수단이며, 서로 무관한 두 프로세스가 동일한 논리적 메모리 영역에 접근할 수 있게 한다. 공유 메모리를 이용하면 실행 중인 두 프로세스가 자료를 아주 효율적인 방식으로 주고받을 수 있다. IPC가 한 프로세스를 위해 생성한 공유 메모리는 그 프로세스의 주소 공간에서 특 정 범위를 차지한다. 공유 메모리는 여러 프로세스들이 자료를 공유하고 주고받는 효율적인 수단이 된 다. 이 때, 공유 메모리 자체는 동기화 수단을 제공하지 않아서 해당 프로그램이 책 임져야 한다. *함수) -shmget : 공유 메모리 생성 /변수 : (key_t key,size_t size,int shmflg) -shmat : 프로세스의 주소공간에 부착 -shmdt : 공유 메모리를 현재 프로세스에서 떼어낸다.(detach) -shmctl : 공유 메모리를 제어하는 용도(공유메모리 식별자, 명령, 공유메모리의 모 드들과 권한들을 담은 구조체 포인터)
  • 45.  메시지 큐(Message queue) ◦ IPC의 한 방법으로 명명된 파이프와 여러모로 비슷한 반면, 파이프를 열고 닫는 데 관련된 번잡함이 없다. 그러나 꽉 찬 파이프에 의한 실행 차단 등 명명된 파이프에 서 발생할 수 있는 문제들은 메시지 큐에도 여전히 존재한다. 메시지 큐를 이용하면 서로 무관한 두 프로세스가 자료를 상당히 쉽고 효율적으로 주고 받을 수 있다. 명명된 파이프와 달리 메시지 큐는 전송 프로세스와 수신 프로 세스 모두에 독립적으로 존재한다. 이 덕분에 파이프에서 열기와 닫기를 동기화할 때 생기는 어려움을 피할 수 있다. -한 프로세스가 다른 프로세스에게 자료 블록을 전달하는 수단. 각 자료 블록이 자신의 종류를 구분하는 값을 가지고 있어서 수신 프로세스는 서로 다른 종류의 자료 블록들을 독립적으로 받을 수 있고, 처리가 복잡해질 수 있다. 또 파이프와 마찬가지로 각 자료 블록의 크기에는 상한이 존재하며, 시스템 전반의 모든 대기열에 담을 수 있는 블록들의 전체 크기에도 상한이 존재한다.
  • 46.  메시지 큐 함수 ◦ #include <sys/msg.h> int msgctl(int msgid, int cmd, struct msgid_ds* buf); int msgget(key_t key, int msgflg); int msgrcv(int msgid, void* msg_ptr, size_t msg_sz, long int msgtype, int msgflg); int msgsnd(int msgid, const void* msg_ptr, size_t msg_sz, int msgflg); <함수> Msgget : 메시지 큐에 접근할 때 사용하는 함수. Msgsnd : 메시지 큐에 하나의 메시지를 전송할 때 사용하는 함수. Msgrcv : 메시지 큐에서 메시지를 받을 때 사용하는 함수. Smgctl : 메시지 큐를 제어하는 함수. (공유 메모리의 제어 함수와 아주 비슷)
  • 47.  각각의 IPC 상태보는 명령어(터미널 창에서) ◦ 세마포 상태 보기  ipcs –s ◦ 공유 메모리 상태 보기  ipcs –m ◦ 메시지 큐 상태 보기  ipcs -q
  • 48.  소켓이란..? ◦ Ch13, 14장에서 다루었던 것과 근본적인 차이를 보인다. 소켓에 서는 여러 컴퓨터들의 경계를 넘나들 수 있다. 소켓의 사용 방법은 파이프 사용 방법과 매우 비슷하지만, 여러 컴 퓨터들의 네트워크를 가로질러서 자료를 주고받을 수 있는 능력 은 소켓에만 해당된다. 한 컴퓨터의 프로세스는 소켓을 통해서 다 른 컴퓨터의 프로세스와 통신할 수 있으며, 이를 통해서 네트워크 상에 분산된 클라이언트/서버 시스템을 구축할 수 있다. ex) 원격 인쇄, 데이터베이스 연결, 웹 서버 기능 등. ◦ *소켓 인터페이스는 Windows도 지원하며, 윈속(WinSock)이라고 부른다.
  • 49.  주제 ◦ 소켓 연결의 작동 방식 ◦ 소켓의 특성들과 주소, 통신 ◦ 네트워크 정보와 인터넷 데몬 ◦ 클라이언트와 서버
  • 50.  소켓 연결 ◦ 1. 서버 응용프로그램이 소켓을 생성한다. 서버는 시스템 호출 socket을 이용, 소 켓을 생성.(이 소켓은 다른 프로세스와 공유되지 못한다. ◦ 2.서버 프로세스는 그 소켓에 하나의 이름을 부여한다. 네트워크 소켓의 경우 클라 이언트가 연결할 수 있는 특정 네트워크에 관련된 서비스 식별자가 부여된다. 소켓에 이름을 부여할 때 사용하는 시스템 호출은 bind 이다. 이름을 부여한 후, 서버 프로세스는 해당 소켓에 클라이언트가 연결되기를 기다린다. 이를 위한 시스 템 호출은 listen이며, 이 함수는 들어오는 연결을 위한 대기열을 생성한다. 연결 요청이 들어오면 서버는 시스템 호출 accept를 이용해서 그 요청을 받아들인다. 서버가 accept를 호출하면, 명명된 소켓과는 개별적인 새로운 소켓이 생성된다. 이 새 소켓은 해당 클라이언트 하나와의 통신에만 쓰인다. -클라이언트 쪽의 소켓 기반 시스템은 훨씬 간단하다. 클라이언트는 socket을 호출해서 이름없는 소켓을 생성, 그 다음에는 서버의 명명된 소켓을 주소로 사용해 connect를 호출함으로써 서버와의 연결을 만든다.
  • 51.  소켓 특성들. ◦ 소켓을 규정하는 가장 중요한 특성 세 가지는 도메인, 종류, 프로토콜 이다. ◦ 소켓은 또한 주소로 쓰이는 이름도 가지는데, 주소의 형식은 도메인에 따라 다르다. ◦ 도메인을 프로토콜 패밀리라고 부르기도 한다. ◦ 소켓 도메인.  도메인은 소켓 통신이 사용할 네트워크 매체를 결정한다. 가장 흔히 쓰이는 소켓 도메인은 AF_INET으로, 이것은 인터넷 자체는 물론 여러 리눅스 근거리 통신망에도 쓰이는 인터넷 네트워킹에 해당한다. 이 도메인의 프로토콜 패밀리는 인터넷 프로토콜(IP)이다. 인터넷 프로토콜에서 네트워크상의 특정한 컴퓨터를 지칭하는 데 쓰이는 주소 형식은 IP주소 하나뿐이다
  • 52.  소켓의 종류 ◦ 스트림 소켓  표준 입, 출력 스트림과 다소 비슷한 면을 가진 스트림 소켓은 순차적인, 그리고 신뢰성 있 는 양방향 바이트 스트림 방식의 연결을 제공한다.(신뢰성 : 전송된 자료가 오류가 보고되지 않고 소실되거나, 복제되거나, 순서가 바뀌는 일은 없다는 뜻) ◦ 데이터그램 소켓  연결의 유지 및 관리를 수행하지 않는다. 또한 이 종류의 소켓에서 보낼 수 있는 하나의 데 이터그램의 크기에는 한계가 주어져 있다. 데이터그램은 도중에 소실되거나, 중복되거나, 다른 데이터그램과 순서가 바뀔 수 있다. (UDP/IP 연결을 통해 구현된다.)  순차성과 신뢰성을 보장하진 않지만, 네트워크 연결을 유지할 필요가 없기 때문에 자원 효 율성이 좋다. 연결 설정하는데 소요 시간이 없기 때문에 속도도 빠르다. ◦ 소켓 프로토콜  소켓 종류의 전송 메커니즘이 여러 개의 프로토콜들을 제공하는 경우 프로그램은 그 중 하 나를 선택할 수 있다. 책에서는 다른 소켓 프로토콜은 사용하지 않았다.
  • 53.  소켓 생성 ◦ int socket(int domain, int type, int protocol);  domain 은 소켓의 주소 패밀리를 결정  type 는 소켓에 쓰일 통신의 종류를 결정.  protocol은 그 통신을 위한 프로토콜을 결정.  Socket 시스템 호출은 하나의 서술자를 돌려주는데, 이것은 저수준 파 일 시스템 서술자와 여러모로 비슷하다.  소켓이 연결되면 이 서술자로 시스템 호출 read, write를 호출, 자료를 읽거나 쓸 수 있다. 소켓 연결을 끝낼 때에는 close 사용.
  • 54.  소켓 이름 붙이기 ◦ int bind(int socket, const struct sockaddr* address, size_t address_len);  Bind 시스템 호출은 socket 변수로 지정된 이름 없는 소켓에 address 매개변수 로 지정된 주소 구조체에 담긴 주소를 부여한다.  Bind를 호출할 때에는 특정 주소 구조체 포인터를 반드시 일반적인 주소 형식 포인터(struct sockaddr*)로 강제 형변환해야 한다.  bind는 성공 시 0을, 실패 시 -1을 반환.
  • 55.  소켓 연결 대기열 만들기 ◦ int listen(int socket, int backlog);  backlog 변수는 listen이 생성할 대기열의 크기, 즉 대기열에 담을 수 있는 연 결 요청들의 최대 개수이다.  listen함수는 성공 시 0을, 실패 시 -1을 돌려준다.
  • 56.  연결 수락 ◦ Int accept(int socket, struct sockaddr* address, size_t* address_len); Accept 시스템 호출은 socket 변수로 지정된 소켓에 클라이언트가 연결을 시도하길 기다린다. 그 클라이언트는 소켓의 대기열의 첫 번째 연결 요청에 해당한다. accept는 그 클라이언트의 통신을 위한 새 소켓을 생성한 후 그것의 서술자를 반환 한다. 새 소켓은 서버의 청취 소켓과 같은 종류이다. - socket 변수에는 반드시 bind로 명명, listen으로 대기열을 만든 소켓의 서술자를 지정해야 한다. -address 변수가 가리키는 곳에는 연결된 클라이언트의 주소 구조체가 설정된다. -address_len 변수에는 클라이언트 주소 구조체의 길이를 담은 변수의 주소 설정. *소켓의 대기열에 연결 요청이 하나도 없으면 accept 호출이 차단되며, 클라이언트 가 연결을 요청하면 비로소 서버 프로세스의 실행이 재개된다
  • 57.  연결 요청 ◦ int connect(int socket, const struct sockaddr* address, size_t address_len);  Socket 변수는 클라이언트쪽 소켓의 서술자이고 address는 서버쪽 소켓의 주 소를 담은 구조체를 가리킨다.  Address_len은 그 구조체의 길이이다.  Socket변수에는 반드시 socket 호출로 얻은 유효한 서술자를 지정해야한다.  connect는 성공시 0, 실패시 -1을 돌려준다.  소켓 닫기 ◦ Close를 호출해서 소켓연결을 끝낼 수 있다.
  • 58.  다중 클라이언트 ◦ 하나의 서버에 여러 개의 클라이언트들이 동시에 연결하 는 경우.  서버 프로그램 측에서 fork를 이용, 다중 클라이언트를 처리할 수도 있 으며 select 함수를 이용하여 처리 할 수도 있다.  여기서 select란, 시스템 호출로써 저수준 파일 서술자들을 하나의 단 위로 취급해서 그것들 중 하나에 입력이 들어오기를(또는 출력이 완료 되길) 기다릴 수 있다. 만약 다중 클라이언트에서 사용한다면, 서버 쪽 청취 소켓과 클라이언트 연결 소켓 모두를 동시에 기다린다. 둘 중 하 나라도 활동이 감지되면, 모든 가능한 파일 서술자를 점검, 어떤 소켓 이 깨어났는지 파악, 그에 따라 적절한 처리를 수행한다.  서버 쪽 청취 소켓에 입력이 들어왔다면 어떤 클라이언트가 서버와의 연결을 시도한 것이다. 이 경우 차단을 걱정하지 않고 accept를 호출 할 수 있다.
  • 59.  간단한 실습 (client 쪽, client1.c) 그냥 client1만 실행시키면, Server와 같이 실행시키면
  • 60.  간단한 실습(server1.c 서버 쪽) ./server1 & 을 입력, server1을 백그라운드 작업하여 client1을 실행시키는데, ./server1 & 후 ps 의 상태는, 그리고 서버는 파일 시스템상의 소켓을 생성하는데 그 파일은 ls 명령으로 볼 수 있다 다 사용한 소켓은 제거하는 것이 좋다. (프로그램이 신호에 의해서 비정상적으로 종료되었다면, 소켓이 남아 있는지 확인, 제거해야 파일 시스템이 지저분해지는 것을 피할 수 있다.
  • 61.  간단한 실습에 대한… ◦ 서버는 클라이언트가 기록한 문자 하나를 읽어서 그것을 증가한 후 다시 클라이언트에게 보낸다.(출력하는 건 클라이언트 측)
  • 62. 더 상세히 공부하고 싶었지만 처음 책을 정독한것에 대해 만족을 하며, 프로그래밍을 할 때, 다시 책을 볼 때, 좀 더 코드 부분과 직접 프로그래밍하는거 에 중점을 둘 필요가 있다고 생각이 드는 공부였다. 그리고 중요하다고 생각되는 부분만 공부하였는데 차후에 공부할 때에는 다른 부분도 공부를 해야겠 다. 또 소켓 프로그래밍 같은 부분은 따로 책이 있 으니 그 부분에 대해서 더 공부할 필요성이 느껴진 다.