[sw정글-북] 📚CSAPP 11장-Network Programming
카테고리: swjungle CSAPP
📚📚CSAPP 11장-Linking
🚀노션에서 업데이트 된 내용으로 보기
📚CSAPP 11장 <== 클릭
📚CSAPP 11장 <== 클릭
📚CSAPP 11장 <== 클릭
📕start
- 11.1 The Client-Server Programming Model
- 클라이언트-서버 모델
- 모~~든 네트워크 응용프로그램은 클라이언트-서버 모델
- 한개 이상의 서버 프로세스, 한개 이상의 클라이언트 프로세스로 구성
- 모든 근본 연산은 transaction
- 1.주문하면
-
- 음식받아오고
- 3.손님한테음식주고
-
4.손님이 음식 맛본다
- 클라이언트-서버 모델
- 11.2 Networks
- 컴퓨터에 키보드 마우스 꽂으면 I/O 디바이스로 인식됨
- 컴퓨터에게 네트워크도 그저 또다른 I/O 디바이스임
- 키보드 꽂으면 글자가 들어옴
- 랜선 꽂으면 (검색결과, 유튜브 등)정보가 들어옴
- 이더넷
- 네트워크는 기하학적 구조
- 하위수준은 LAN(Local Area Network)
- 대중적인 LAN기술: Ethernet
- 하위수준은 LAN(Local Area Network)
- 꽂으면 바이러스마냥 번식해나감
-
Host는 상위 주소를 물려받음(아 이사람이 내 엄마구나)
- 허브보다 상위개념, 브릿지
-
라우터
- point-to-point 전화연결 가능
- WAN(Wide-Area-Network) 사례
- 인터넷은 여러가지 LAN과 WAN들로 이루어져 있음
Protocol Software
- 데이터를 (여기(host))에서 — — — — — — —(저기(host)) 까지 어떻게 이동시켜야 함
- 비호환적(incompatible)인 네트워크들을 지나, data bits를 다른 목적지 host까지 옮겨야함
- 정답:
Protocol software
의 layer들을 통해 해결 가능- 호스트랑 라우터 돌면서, 어떻게 작동할지 프로토콜 구현해둔 것
- 작명 방법:
- 서로다른 LAN기술, 그냥 통일된 포맷 정의
- 네트워크계의 주민등록번호, 집주소 같은거임
- 중복되지 않는(구별지을 수 있는) 방법
- 전달 방법:
패킷
(packets)이라는 비연속적인 단위로 묶는 방법- 패킷 구성
헤더
- 패킷 크기
- 출발지 호스트 주소
- 목적지 호스트 주소
payload
- 출발지 호스트가 보낸 데이터
-
프로토콜은 어떻게 동작하는가
- 호스트A(철수)가 호스트B(영희)에게 카톡을 보내야함
- 카톡 전송버튼 누름(시스템콜 호출!!!)
protocol software
이 LAN1 프레임을 생성- header에 철수, 영희주소 찍고
- payload에 메시지 내용
- 만든 프레임을 라우터까지 보냄
- 라운터는
protocol software
한테 보냄- LAN1프레임의 헤더부분 (살짝)벗겨봄
- 아 이거 영희한테 주면 되네?
- LAN2프레임으로 다시 감싸줌
- 만든 프레임을 영희한테까지 보냄
- 영희컴퓨터는
protocol software
한테 보냄- 헤더부분 벗겨봄
- payload까지도 다 벗김
- (철수가 보낸 메시지가 드디어 개봉박두)
- 영희컴퓨터가 시스템콜로 메시지(데이터) 읽어들임
- 문제점
- 네트워크별, 최대 프레임 크기가 다르다면?
- 라우터들은 어디로 프레임 보내줄지 알 수 있을까?
- 라우터들은 네트워크 구조가 변경되면 앎?
- 패킷이 손실되면?
- 해결: 🔑»> 캡슐화 «<🔑
- 호스트A(철수)가 호스트B(영희)에게 카톡을 보내야함
- 네트워크는 기하학적 구조
- 11.3 The Global IP Internet
- 인터넷(표현법)
- Internet: 글로벌 IP Internet
- internet: 일반적인 개념
- Internet은 internet을 성공적으로 구현한 것
TCP/IP
- (Transmission Control Protocol / Internet Protocol)
- 호스트는
TCP/IP
가 구현되어있는protocol software
를 실행 - 모든 컴터에서 지원
- 여러가지 프로토콜의 집합임
- 여러가지 내용이 있기에 (이 챕터에서)그냥 추상화시켜서 TCP/IP를 하나의 독립 프로토콜로 생각
- 내부의 여러가지 프로토콜들
- IP
- 배달 메커니즘 제공
- 호스트 ⇒ 호스트 전송
- UDP
- IP를 조금 확장한 것
- 프로세스 ⇒ 프로세스 전송
- TCP
- IP위에 구현한 프로토콜
- 프로세스간 완전 양방향 연결 제공
- (full-duplex(bidirectional) connection)
- IP
- 통신할 때..
- 소켓인터페이스 & Unix I/O함수들을 혼합해서 사용
- 소켓함수들은 시스템콜들로 구현
- 시스템콜은 커널에서 트랩을 발생
- 발생된 트랩은 TCP/IP에서 다양한 커널모드 함수들을 호출
IPv4
,IPv6
- IPv4의 후속이 IPv6
- 사람들이 아직도 IPv4밖에 안씀
- 여기서는 그냥 IPv4로만 설명
- 11.3.1 IP Addresses
- xx.xxx.xxx.xx 이런 숫자들임
- 자세한 설명 생략
- 11.3.2 Internet Domain Names
-
Domain name hierarchy
- 맨~첫번째 단계(따로 카운팅 안하는듯 함)
- 이름이 없는 루트노드
first-level
- ICANN(Internet Corporation for Assigned Names and Numbers)이 만듬
- .com .edu .net 등등
second level
- ICANN이 인정한 대행사들이 요청한 순서에 의해 이름 할당
- 일단 cmu.edu를 할당받고나면…
- cs.cmu.edu (컴공)
- ee.cmu.edu (전기전자)
- 등등 서브도메인 내에서 어떤 이름이나 마음대로 생성 가능
- 맵핑
- 예전에는 HOSTS.TXT 한개로 수동관리(ㅠㅠ)
- 이젠 DNS(Domain Name System)
- 전세계에 분산된 데이터베이스
- 수백만개의 호스트들
- 각각 도메인이름, IP주소들의 equivalence한 클래스들
- 도메인이름의 IP주소를 표시하는 NSLOOKUP이라는 리눅스프로그램들이 있음
- local host
- 인터넷 호스트들은 각각 본인들의 localhost를 가지고 있음
- localhost들은 127.0.0.1이라는 loopback주소에 맵핑
- 맵핑 개수(1:1, N:1, 1:N)
- 어쩌고저쩌고.com
- IP주소 하나 나올수도 있음
- IP주소 여러개 나올수도 있음(1:N 맵핑)
- 저쩌고저쩌고.com
- 어쩌고저쩌고.com이랑 같은 IP주소 나올수도 있음(N:1 맵핑)
- 어쩌고어쩌고.com
- 아예 맵핑되어있지 않을수도 있음(유효한데… IP주소가 없다..?ㄷㄷ)
- 어쩌고저쩌고.com
-
- 11.3.3 Internet Connections
- 연결(connection)이 이루어 지면…
- byte stream을 주고받을 수 있음
- 두개의 프로세스를 연결한다는 점에서
point to point
- 데이터가 양방향으로 흐른다는 점에서
full-duplex
socket
- 연결의 종단점
- 인터넷 주소와 16비트 정수 포트
- address: port로 표현
ephemeral
포트- 클라이언트가 연결 요청하면, 커널이 포트 자동 할당되는 포트
- 클라이언트 소켓주소 내에 있음
- ephemeral = 단기적
- 하지만 서버에서의 포트는..?
- 영구적으로 해당 서비스에 연결되는 포트들이 있음
- 웹서버
- 포트번호: 80
- 맵핑된 이름: http
- 이메일 서버
- 포트번호: 25
- 맵핑된 이름: smtp
- 이름과 포트간의 mapping은 /etc/services 파일에 보관되어 있음
- 연결은 유일무이함
- 연결 식별법
-
두개의 end-point의 소켓주소로 식별
-
socket pair로 알려져 있음, tuple로 표시
- (128.xxxx.242:51213, 208.xxxxxx.15:80) ←튜플
- 51213은 ephemeral port
- 80은 well-known port
-
- 연결(connection)이 이루어 지면…
- 인터넷(표현법)
-
11.4 The Sockets Interface
- 소켓 인터페이스는 Unix I/O 함수들과 같이 사용되는 함수들의 집합
- 11.4.1 Socket Address Structures
- 리눅스 커널 입장에서 소켓은 통신을 위한 end point
-
리눅스 커널 입장에서 소켓은 열려있는 파일
typedef struct sockadder SA; <- 이렇게 정의하면 됨 /* 👇👇👇옛날시절...sockaddr_in으로 정의👇👇👇*/ /* 여기서 in은 인터넷임*/ struct sockaddr_in { uintl6_t sin_family; /* 프로토콜들*/ uintl6_t sin_port; /* 포트번호 */ struct in_addr sin_addr; /*IP 주소 */ unsigned char sin.zero [8]; }; /* Generic socket address structure (for connect, bind, and accept) */ struct sockaddr { uintl6_t sa_family; /* Protocol family */ char sa_data[14] ; /* Address data */ };
- 11.4.2 - socket()
- 클라이언트와 서버가 소켓식별자(
socket descriptor
)를 생성하려고 사용 clientfd
리턴됨
- 클라이언트와 서버가 소켓식별자(
- 11.4.3 - connect()
- 클라이언트가 호출하면 서버와의 연결 수립
- 소켓주소 addr의 서버와 인터넷연결 시도
- 함수실행
- 성공 전까지: 블럭되어있거나 에러 발생
- 연결 성공하면: clientfd descriptor(식별자)는 읽고 쓸 준비 됨
- (x:y, addr.sin_addr:addr.sin_port)
x
클라이언트의 IP주소y
ephemeral 포트- 클라이언트 호스트의 클라이언트 프로세스를 유일하게 식별함
- 11.4.4 - bind()
- 서버가, 클라이언트랑 연결하려고 사용
- 커널에게, “addr에 있는 서버주소를 sockfd와 연결해줄래?” 물어봄
- 이 FD소켓에 serv_addr주소를 할당하겠다
- 11.4.5 - listen()
- 서버가, 클라이언트랑 연결하려고 사용
- 듣기 시작
- 11.4.6 accept()
-
서버가, 클라이언트랑 연결하려고 사용
- 듣기식별자
- 한번만 생성됨
- 클라이언트 연결 요청에 대해 end point 역할
- 서버가 살아있으면 계속 존재
- 연결 식별자
- 서버와 클라이언트 사이에 성립된 연결의 끝점
- 서버가 연결요청을 수락할 때마다 생성
- 서비스하는 동안에만 존재
-
- 11.4.7 Host and Service Conversion
- getaddrinfo()
- getnameinfo()
- 11.4.8 Helper Functions for the sockets Interface
- open_clientfd()
- 클라이언트가 실행시킴
- 서버와의 연결 설정
- open_listenfd()
- 연결요청을 받을 준비가 된 듣기 식별자 생성
- open_clientfd()
- 11.4.9 Example Echo Client and Server
- FD = file descriptor
- SD = socket file descriptor
- 11.5 Web Servers
- 11.5.1 Web basics
- FTP 전통적인 파일 전송 서비스
- 웹 서비스는 HTML이라는 언어로 작성될 수 있다
- 11.5.2 Web content
-
MIME
(Multipurpose Internet Mail Extentions)- 웹클라이언트와 서버에게, 컨텐츠는 연관된 MIME타입을 갖는 바이트 배열(뭔 소리야…)
- 그냥 MIME은 위그림처럼 파일형식임
-
URL
(Universal Resource Locator)- 실행파일을 위한 URL은 뒤에 인자 포함 가능
:
포트번호 인식?
파일 이름과 인자를 구분&
각 인자를 구분
- 어떻게 쓸지 규칙 없음
- 동적인지 정적인지 구분짓는 방법? 그냥 자기마음대로 해도됨
- 실행파일 디렉토리? 자기 마음대로 해도 됨
/cgi-bin
은 그냥 (관습적으로 사용하는)고전적인 방식의 실행파일 디렉토리
-
내 블로그가 작동하지 않았던 이유
- 실행파일을 위한 URL은 뒤에 인자 포함 가능
-
- 11.5.3 HTTP transactions
- HTTP표준
- 모든 텍스트라인이 carriage return
\r
과 line feed\n
쌍으로 종료될것을 요구
- 모든 텍스트라인이 carriage return
- 요청
- 요청방법
-
(method) (URI) (version)
- GET / HTTP/1.1
- http://localhost:8000/cgi-bin/adder?15000&213
- GET / http://localhost:8000/cgi-bin/adder?15000&213 HTTP/1.1
-
- 메소드
- 메소드 종류
GET
,POST
,OPTIONS
,HEAD
,PUT
,DELETE
,TRACE
GET
- 서버에게 URI에 의해 식별되는 내용을 리턴할것을 지시
- HTTP요청의 대부분이 GET 메소드임
- 메소드 종류
- URI
- 파일 이름과 옵션인 인자들을 포함하는 URL의 접미어
- version
- 요청이 준수하는 HTTP버전을 명시
- 1.1 가장 최신 버전
- 1.0은 1996부터 사용되고 있는…(TBD: 위키 검색해두기)
-
코드분석
- GET / HTTP/1.1 뜻
- HTML 파일 index.html을 가져와서 리턴해라
- 나머지 요청들도 HTML/1.1 포맷이다
- Host: www.aol.com
- HTTP/1.0에서는 없었음 (1.1부터 등장한 헤더)
- 이와같은 Host헤더는 프록시 캐시에 의해 사용되었음
- 서버사이의 중간자 역할을 함
- Multiple proxies
- 하나의 서버와 하나의 클라이언트 사이에 존재
- proxy chain속에 존재
- GET / HTTP/1.1 뜻
- 요청방법
- 응답
- 요청과 비슷
- 응답방법
-
(version) (status-code) (status-message)
- 버전
- 준수해야 할 HTTP 버전 설명
- 상태코드
- 200, 400, 403, 505 이런거임
- 이처럼 3비트양수로 표시됨
- 상태메시지
- 그냥 상태코드랑 같이 따라다님
- 버전
-
-
응답에서 중요한 것
- Content-Type, Content-Length 두개가 중요함
- HTTP표준
- 11.5.4 Serving Dynamic Content
- 자기가 만든 자식프로세스에게 인자를 전달해주는 방법⇒ CGI(Common Gateway Interface)로 설명 가능
-
CGI 환경변수
- ? 로 파싱
- GET /cgi-bin/adder?15000&213 HTTP/1.1 요청을 받으면?
- fork를 호출해서 자식 프로세스를 생성하고,
execve
실행execve
⇒ exec + vv
vector로 인자를 하나 받는다e
설정할 환경변수를 파라미터로 받는다- 추가
- l : argv가 list로 나열된다는 의미입니다. 그 것의 끝은 NULL.
- p : 첫번째 파라미터인 명령어/실행파일이 PATH로 지정된 디렉토리에 있다면 full path 또는 상대 path로 하지 않아도 된다는 뜻
- 호출된
execve
를 통해 /cgi-bin/adder 프로그램을 자식 컨텍스트에서 실행- adder같은 애들도 CGI로 불리우기도 함(CGI표준 준수하기 떄문)
2-1. 사실 자식프로세스는 execve실행되기 전, CGI의 QUERY_STRING을 입력받은 15000&213로 설정
2-2. 런타임에 리눅스의 getenv함수로 설정된 값을 참조
- fork를 호출해서 자식 프로세스를 생성하고,
- 11.5.1 Web basics
- 11.6 Putting It Together: The Tiny Web Server
- 👇코드분석👇
- Main()
- while(1)로 무한루프 호출해두고
- 연결시켜두고 무한대기
- 무엇인가 입력이 있어야!!! doit이 실행되는거임
- Doit()
- 한개의 HTTP트랜잭션을 처리
- rio_readlineb()으로 요청을 읽어옴
- GET 메소드만 지원
- POST를 요청받으면? ⇒ 에러출력하고 main으로 돌아옴
- read_requesthdrs(&rio); 로 헤더 읽고 다른거 무시
- parse_uri()실행
- CGI 인자 스트링으로 분석, static? dynamic? 결정
- 드디어.. 대망의 요청 실행
- 스태틱 실행!
- 권한검사!!!! (!(S_ISREG(sbuf.st_mode)) I I !(S.IXUSR & sbuf.st_mode))
- 권한없다? ㅋㅋ 바로 에러메시지
- 이상없으면 스태틱 실행!
- 다이나믹 실행
- 권한검사!!!! (!(S_ISREG(sbuf.st_mode)) I I !(S.IXUSR & sbuf.st_mode))
- 실행안됨? ㅋㅋ 바로 에러메시지
- 이상 없으면 다이나믹 실행
- 스태틱 실행!
- clienterror()
- 그래도 웬만한 에러메시지 다 올려줌
- read_requesthdrs()
- \r\n으로 개행 될때까지 읽어옴
- 11.7 Summary
내놔라
/이 파일을
/HTTP/x.x
😵배우면서 깨달은 내용을 정리해 보았습니다. 틀린 것 같은 개념을 아래 댓글에 달아주시면 감사합니다😵
🌜 Thank you for reading it. Please leave your comments below😄
댓글 남기기