ICE3013 시스템 프로그래밍 강의 정리

· by 박승재

이 글은 인하대학교 ICE3013 시스템 프로그래밍 강의를 기준으로 작성되었습니다.

강의 과제 솔루션을 찾으신다면 과제 솔루션을 방문해주세요.

1주차

pwd, ls, echo, cd, grep기본적인 명령어>(redirect), |(pipe)와 같이 명령창 출력 결과를 다루는 법을 배웁니다.

man 명령어를 이용하면 쉽게 명령어 사용법을 찾을 수 있습니다.

특히 grep|(pipe)를 이용한 명령은 자주 사용하게 되니 꼭 알아주시고 넘어가야 합니다.

2주차

vi 명령을 이용해 Vi 에디터를 열고 파일을 작성하는 법을 배웁니다.

Vi 에디터 자체에 다양한 설정이 있는데 필요하신 분께 제가 사용했던 설정파일을 공유해드립니다: .vimrc

$ vi ~/.vimrc

위와 같이 파일을 여신 후, 위의 파일을 복사해 붙여넣어(마우스 우클릭)주면 됩니다.

2번째 수업에서는 gcc를 이용해 C 코드를 컴파일하는 법과 xxd, ps 명령어를 배웁니다.

C 언어 컴파일로 G++을 사용할 수도 있지만 C++을 혼합해 사용하는 것이 아니라면 개인적으로 GCC 사용을 추천합니다.

강의에서는 GCC에 여러 가지 옵션을 주는 법을 안 가르쳐 주는데, 컴파일 시 -Wall -Wextra 옵션을 붙여주면 코드의 잠재적인 위험요소를 경고해줍니다.

또한, for 안에서 변수 선언 등 C99에서만 지원하는 문법을 사용하려면 -std=c99 옵션을 주면 됩니다.

gcc -Wall -Wextra -std=c99 -o example example.c

앞으로 강의자료에 void main(), int main(), int main(void)등 다양한 main 함수 선언이 혼재되어 나오는데 C/C++ 표준 main 함수를 참고하시면 기초를 다지는데 도움이 될 것입니다.

위 글의 내용을 요약해드리자면 C 언어에서는 int main(void)를 사용하는 것이 가장 표준적인 방법입니다.

3주차

C 언어에서 문자열을 다루는 법을 배웁니다.

C 언어의 문자열은 항상 '\0'으로 끝나야 하는 것에 유의하며 strcpy, strlen 등의 함수를 사용해야 합니다.

strtok 함수는 원본 문자열을 수정하며 한 번에 하나의 문자열만 입력할 수 있는 것에 주의해야 합니다.

문자열에서 헷갈릴 수 있는 부분은 C 문자열: 리터럴, 포인터, 배열 글에서 정리해두었습니다.

4주차

3주차에 배운 문자열을 이용해 파일을 수정합니다.

강의의 일부 코드는 open으로 생성한 파일 디스크립터를 close하지 않고 main 함수를 종료시키는 경우가 있는데 다 쓴 파일 디스크립터는 close하는 것이 맞습니다.

파일에서 읽어온 문자열을 다룰 때 VLA(가변 길이 배열)을 이용해 코드를 간단하게 만드는 꼼수(?)가 있는데, VLA에 대해서는 C/C++ 가변 길이 배열(Variable-length Array): C언어 표준이었던 것을 읽어보시면 도움이 됩니다.

GDB 사용법은 Visual Studio, CLion 같은 IDE를 사용해 코딩하고 결과를 붙여넣는 식으로 코딩을 하면 잘 사용할 일 없지만, 과제에서 사용법을 물어보는 경우도 있으므로 기본적인 방법은 익혀두는 것이 좋습니다.

5주차

WAV 파일의 포맷을 분석하고 WAV 파일을 수정하는 법을 배웁니다. 중간고사 기출문제로 유서 깊은 내용이니 꼭 원리를 이해해야 합니다.

파일의 헤더를 읽을 때 char, short, int의 형태(문자, 정수)에 집중하지 말고 그냥 자료형의 크기만큼 파일을 읽어간다고 생각하시면 됩니다.

그리고 C언어에서는 문자가 정수로 표현되니 char은 -127~128의 정수라 생각하셔도 별 차이 없습니다.

fopenopen의 차이점에 대해서는 C 파일 입출력: 시스템 콜 vs 라이브러리 함수에 정리해두었습니다.

6주차

main 함수의 두 인자 int argc, char* argv[]를 이용해 사용자로부터 실행인자를 가져오는 법을 배웁니다.

이쯤 되면 코드의 복잡도가 상당히 올라가기 때문에 대부분 함수를 이용해 로직을 분리하려 시도합니다.

이때 배열은 함수의 인자로 넘기게 되면 Array to Pointer Decay라 불리는 현상이 발생하는데 강의에서는 안 가르쳐주기 때문에 이 부분에서 많이 애를 먹습니다.

참고: C/C++ Array Decay: 배열이 있었는데요 없었습니다

7주차

fork 함수로 프로세스를 나누는 법을 배웁니다.

fork를 기점으로 부모 프로세스와 자식 프로세스가 나뉘어 병렬적으로 실행되기 때문에 프로그램의 흐름을 놓치게 되면 코딩하는 데 상당히 어렵습니다.

또한 printf 함수는 병렬적으로 호출하면 출력이 꼬이는 경우가 있는데 이때는 fflush(stdout)으로 표준출력스트림을 강제로 비워주면 문제를 해결할 수 있습니다.

exit 함수로 자식 프로세스를 종료시킬 때는 exit(0)보다 exit(EXIT_SUCCESS)과 같이 좀 더 명시적으로 작성하는 것이 흐름을 파악하기에 유리합니다.

8주차

중간고사 시험입니다.

과제에서 문제가 나오며 족보에서 문제가 그대로 나오지는 않지만 풀어보는 것은 도움이 됩니다.

대부분 C 언어로 문자열을 얼마나 잘 다루느냐가 성적을 결정하게 됩니다.

중간에 막히지 않는다면 시간은 여유로운 편입니다.

9주차

외부 프로그램을 execve 함수로 호출하는 것을 배웁니다.

이번 강의는 순한 맛입니다.

10주차

9주차의 응용 버전입니다. wait 함수로 프로세스의 작동 시점을 제어할 수 있습니다.

문자열 처리가 어려워지기 시작하며 strtok 함수를 잘못 사용할 경우 문자열끼리 서로 범위가 겹치는 버그가 발생하기도 합니다.

문자열에서 막힐 경우 3주차 강의를 복습하도록 합니다.

11주차

소켓 프로그래밍입니다.

강의노트에서 제공하는 코드는 변수가 알아보기 어렵게 되어 있어 강의노트를 보고 새로 코드를 짜보는 것도 나쁘지 않습니다.

다른 프로그램과 소켓의 포트가 겹치면 소켓 생성에 실패하기 때문에 겹치지 않게 설정해야 합니다.

강의에서 제공하는 리눅스 PC의 경우 소켓 반환과 회수 사이의 딜레이가 있어 ps 명령어로 소켓을 점유 중인 프로세스가 없음을 확인해도 소켓 생성이 실패하는 버그(?)가 있는데 약 10분 정도 기다리고 다시 시도하면 해결이 됩니다.

12주차

윈도우에서의 소켓 프로그래밍은 리눅스 환경과 미묘하게 다르지만 근본적인 내용은 비슷합니다.

11주차와 마찬가지로 소켓은 open 함수를 이용해 생성하지만 스트림(Stream)임을 유의해 코드를 작성해야 합니다.

제시하는 Simple FTP를 구현하는 과제는 버퍼의 크기보다 큰 파일을 전송할 수 있는지 없는지에 따라 난이도가 달라지게 됩니다.

시간 남으면 해보세요!

13주차

select를 이용해 여러 개의 클라이언트를 수용할 수 있는 서버를 구축하게 됩니다.

마찬가지로 강의노트를 보고 처음부터 코드를 짜보는게 도움이 되며 다양한 데이터가 한 곳으로 집중되므로 데이터가 꼬이지 않도록 신경 써야 합니다.

제시한 채팅 프로토콜을 구현하는 과제는 #define을 이용해 state를 직관적으로 확인할 수 있게 코딩하면 흐름을 파악하기 용이합니다.

14주차

마지막 강의입니다.

기말고사에는 비중있게 안 나올 수 있지만, 상용 서버 프레임워크에서도 내부적으로 이용하는 방식이고 Signal를 아예 모르면 이해할 수 없는 코드도 있는지라 최소한의 개념을 잡고 갑시다.]

15주차

기말고사 시험입니다.

주로 채팅 서버와 같이 소켓 프로그래밍 쪽에서 문제가 나오는 편입니다.

문제 수가 적기 때문에 중간고사보다 시간 압박은 적은 편이나 평소에 과제 솔루션을 베껴왔다면 풀기에는 어려울 것으로 생각합니다.