Network Programming 드디어 통신!클라이언트 서버프로그래밍 모델모든 네트워크 응용 프로그램은 클라이언트 서버 모델에 기초하고 있다.서버는 일부 리소스를 관리하고 이 리소스를 조작해서 클라이언트를 위한 일부 서비스를 제공한다.클라이언트-서버 모델에서 근본적인 연산은 트랜잭션이다.트랜젝션트랜잭션은 네단계로 구성된다.1. 클라이언트가 서비스를 필요로 할 때, 클라이언트는 한 개의 요청을 서버에 보내는것으로 트랜잭션을 개시한다.2. 서버는 요청을 받고, 해석하고, 자신의 자원들을 적절한 방법으로 조작한다.3. 서버는 응답을 클라이언트로 보내고, 그 후에 다음 요청을 기다린다.4. 클라이언트는 응답을 받고 이것을 처리한다. 네트워크네트워크네트워크는 단지 또 다른 I/O 디바이스이다. (네트워크는 ..
System-Level I/OUnix I/O파일은 연속된 m개의 바이트파일을 열때 응용 프로그램은 커널에 I/O 디바이스를 식별할 수 있는 식별자(descriptor) 라고 하는 비음수를 리요청한다.이 식별자는 표준입력(0번) 표준출력(1번) 표준에러(2)로 이루어진 기본 식별자를 가지고 있으며 프로그램의 요청에 의해 식별자가 반환된다.실제 파일의 끝에서 EOF라고 알려진 조건이 발생하면 파일이 종료된다.파일디렉토리는 링크들의 배열로 구성된다.. (점 한개)는 자신의 디렉토리로의 링크이고 ..(점 두개)는 부모 디렉토리로의 링크다. RIO 패키지를 이용한 안정적인 읽기와 쓰기RIO 패키지짧은 카운트를 자동으로 처리하며 네트워크 프로그램으로 인한 통신에서 자료의 손상이 이뤄지지 않게 안정적으로 효율적인 ..
Tiny web server/* $begin tinymain *//* * tiny.c - A simple, iterative HTTP/1.0 Web server that uses the * GET method to serve static and dynamic content. * * Updated 11/2019 droh * - Fixed sprintf() aliasing issue in serve_static(), and clienterror(). */#include "csapp.h"void echo(int connfd);void doit(int fd);void read_requesthdrs(rio_t *rp);int parse_uri(char *uri, char *filename, char *..
OSI 7계층OSI 7계층네트워크에서 통신이 일어나는 과정을 7계층으로 나눈것계층을 나눈 이유통신이 일어나는 과정을 단계별로 파악할 수 있고, 특정 계층에서 문제가 발생하면 문제가 밠애한 계층만 고치면 되기 때문임 1계층 Physical layer물리계층모든 파일과 프로그램은 0과 1의 나열이다. 결국 0과 1만 주고받을 수 있으면 통싱에 성공했다고 할 수 있는 셈.두대의 컴퓨터를 연결했다고 가정했을때, 1을 보낼때는 +5V의 전기를 전선으로 흘려보내고 0을 보낼때는 -5V의 전기를 전선으로 흘려보내면 0과 1의 전송이 가능할 것이다.0과 1을 주고받을 수 있으면 모든 데이터를 주고받을 수 있으므로 컴퓨터간의 통신이 가능해진다.그러나 이 아이디어는 실제에선 잘 동작하지 않는데, 그 이유는 전자기파의 주파..
Exceptional Control Flow제어 흐름처음 전원을 켤때부터 전원을 끄기까지, 프로그램 카운터는 일련의 값들을 순차적으로 가진다.순차적으로 명령을 실행하는 것을 제어 전달이라고 하며, 이러한 제어 전달의 연속은 프로세서의 제어 흐름이라고 한다(flow of control).예외 제어흐름가장 간단한 종류의 제어 흐름은 메모리에서 인접한 위치에 있는 연속된 명령을 수행하는 것이다.하지만 이런 흐름의 급격한 변화는 점프(jumps), 호출(calls), 반환(return)과 같은 익숙한 제어문으로 인해 발생한다.그러나 시스템은 내부 프로그램 변수로 포착되지 않는 시스템 상태의 변화에도 반응해야 하는데, 이는 프로그램의 정상적인 실행과 관련이 없을 수 있다.예를들어 OS가 관리하는 하드웨어 타이머에..
메모리 계층구조메모리 계층구조메모리 시스템은 바이트들의 선형배열이다.CPU 레지스터들은 가장 자주 이용하는 데이터를 보관한다.작고 빠른 캐시 메모리는 비교적 느린 메인 메모리에 저장되어있는 데이터와 인스트럭션을 미리 올려놓아, 상위 메모리에서 보다 빠르게 접근할 수 있게 구성되어있다.메모리 계층의 바닥으로 갈 수록 저렴하고 많은 용량을 저장할 수 있어, 단계적으로 캐시 메모리를 두어 보다 빠르게 데이터에 접근할 수 있게 구성되어있다. 저장장치 기술RAMRandom access memory는 정적램(SRAM), 동적램(DRAM)으로 나뉜다.정적램은 동적램보다 훨씬 더 빠르고 훨씬 더 비싸다.SRAM은 캐시 메모리로 사용되며 CPU 칩 내부 또는 외부에 장착된다 (L1, L2, L3)DRAM은 메인 메모..
Implicit free list 묵시적 가용 리스트의 구현을 위해서는 다음과 같은 메크로가 필요하다.#define WSIZE 4#define DSIZE 8#define CHUNKSIZE (1 (y) ? (x) : (y))#define PACK(size, alloc) ((size) | (alloc))#define GET(p) (*(unsigned int *)(p))#define PUT(p, val) (*(unsigned int *)(p) = (val))#define GET_SIZE(p) (GET(p) & ~0x7)#define GET_ALLOC(p) (GET(p) & 0x1)#define HDRP(bp) (..
Exceptional Control Flow제어 흐름처음 전원을 켤때부터 전원을 끄기까지, 프로그램 카운터는 일련의 값들을 순차적으로 가진다.순차적으로 명령을 실행하는 것을 제어 전달이라고 하며, 이러한 제어 전달의 연속은 프로세서의 제어 흐름이라고 한다(flow of control).예외 제어흐름가장 간단한 종류의 제어 흐름은 메모리에서 인접한 위치에 있는 연속된 명령을 수행하는 것이다.하지만 이런 흐름의 급격한 변화는 점프(jumps), 호출(calls), 반환(return)과 같은 익숙한 제어문으로 인해 발생한다.그러나 시스템은 내부 프로그램 변수로 포착되지 않는 시스템 상태의 변화에도 반응해야 하는데, 이는 프로그램의 정상적인 실행과 관련이 없을 수 있다.예를들어 OS가 관리하는 ..
링커 링킹(linking) 여러개의 코드와 데이터를 모아서 한 개의 파일로 만드는 작업. 로드타임, 실행시에도 수행될 수 있고 독립적인 컴파일을 가능하게 한다. 모듈을 나누고 하나의 모듈만 재 컴파일 하는 방식으로 사용된다. 링커를 이해해야 하는 이유 링커를 이해하면 큰 프로그램을 작성하는데 도움이 된다. 특히 맞지않는 라이브러리 버전때문에 링커 에러가 발생하는 경우는 링커가 참조를 해결해나가는 과정을 이해하고 있어야 해결할 수 있다. 위험한 프로그래밍 에러를 피할 수 있다. 전역변수를 중복해서 정의한 프로그램도 기본 설정의 경우 경고 메시지 없이 링커를 통과할 수 있다. 이런 에러를 예방하려면 링커를 이해해야 함. 링킹을 이해하면 어떻게 언어의 변수 영역 규칙이 구현되는지 이해할 수 있다. 컴파일러 드..
RB_Tree 1. RB_Tree 초기화 rbtree *new_rbtree(void) { rbtree *p = (rbtree *)malloc(sizeof(rbtree)); if (p == NULL) { perror("Failed to allocate memory for RB tree"); exit(EXIT_FAILURE); } // TODO: initialize struct if needed p->nil = (node_t *)malloc(sizeof(rbtree)); if (p->nil == NULL) { perror("Failed to allocate memory for sentinel node"); exit(EXIT_FAILURE); } p->nil->color = RBTREE_BLACK; p->ro..