방학을 맞이했다. 3학년 1학기에는 CS의 꽃인 운영체제와 컴퓨터 네트워크 과목을 수강했다. 두 과목 모두 재밌게 공부했는데, 중요하다고 생각이 든 만큼 블로그에 정리해야할 필요성을 느꼈다. 운영체제는 학기중에 정리해두었지만, 컴네는 아무것도 안해놨다. 까먹기전에 얼른 정리해보도록 하자. 교재는 Computer Network - Top down approach 교재로 공부했으며, ppt를 바탕으로 정리하도록 하겠다.
# 시작하기 전에
네트워크 계층을 정리하는 방법에는 몇가지가 존재한다. OSI 7계층을 시작으로 네트워크의 계층을 나누었지만, 지금 사용되는 실질적인 모델은 TCP/IP의 5계층이다. 각각의 네트워크 레이어 별로 쓰임새가 확실히 정리된다. 사실 처음 강의를 들으면서 Top-down으로 배워나가는게 너무 헷갈렸다. 가장 원초적인것이 뭐를 하는지를 잘 모르기때문이었는데, 종강하고나서 다시 살펴볼때 위에서부터 아래로 배워나가는게 이해가 잘 됐다. 처음 공부할때는 밑에서부터 위로 올라가면서 대략적인 역할을 알아두고, 위에서부터 밑으로 내려가면 더 수월하게 공부 할 수 있을 것 같다는 생각이 들었다.
# Some network apps
우리는 알게 모르게 네트워크를 많이 이용한다. 웹공부를 해봤다면 HTTP프로토콜에 대해서 사용해봤을 것이며, SMTP를 사용하는 메일 등등 수없이 많은 네트워크를 사용한다. 근데 우리가 특정한 웹페이지에 접속한다는 가정하에서 어떤 행동을 취하는지 생각해보자. 소켓을 열거나 이러한 행동을 하지 않는다. Application Layer는 이렇게 최상위 계층으로써 우리가 프로그램(?)이라고 생각하는 것들에 사용방법의 정이라고 볼 수 있다.
프로토콜이라는 말이 많이 등장하게 되는데, 조금 어려운말로 통신규약, 쉬운말로는 어떻게 메시지를 주고받을지에 대한 약속이다. 정의된 프로토콜을 사용한다면 사용방법에 맞는 곳에 메시지를 넣어서 보내면 된다.
# Creating a network app
네트워크 패킷을 전송하기 위해 중간중간 거쳐가는 라우터에는 Application Layer가 존재하지 않으며, end-system에서 보낸 메시지가 end-system에 도착하여 정의한 프로토콜로 해독하여 기능을 한다.
client-server구조와 peer-to-peer구조가 있으며, 메시지를 받는 곳이 어떠한 역할을 해주는지에 따라서 나뉜다고 생각하면 된다.
# Client-server ( 클라이언트 - 서버 )
- 서버(Server)는 항상 켜져있으며, 영구적인 IP를 가진다.
- 클라이언트(Client) 는 서버와 통신하며 서버에 원하는 정보를 요청한다, 필요할때만 연결하고, IP가 변화하여도 된다.
# P2P
P2P는 클라이언트가 서버역할도 같이 하게 된다. 비트 토렌트를 생각하면 된다. 과제로 P2Pf를 구현했었는데 추후에 시간나면 업로드하도록 하겠다.
# Socket
클라이언트가 서버에 데이터를 요청했다며, 어찌어찌하여 요청메시지(request)는 서버컴퓨터에 도착할 것이다. 서버컴퓨터에 도착한 메시지는 최종적으로 실행중인 특정 프로세스에 들어가 해독해야한다. 이 소켓을 통해 메시지를 주고 받는다. 각각의 host들은 32bit의 유니크한 IP주소를 사용한다. 같은 호스트 내에서도 여러개의 프로세스가 돌아가고 있기때문에 호스트를 찾기 위해 16bit의 Port를 사용하는데 소켓이 이러한 것들을 도와주는 창구 역할을 한다.
## Client 소켓
import socket
# 서버의 주소입니다. hostname 또는 ip address를 사용할 수 있습니다.
HOST = '127.0.0.1'
# 서버에서 지정해 놓은 포트 번호입니다.
PORT = 9999
# 소켓 객체를 생성합니다.
# 주소 체계(address family)로 IPv4, 소켓 타입으로 TCP 사용합니다.
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 지정한 HOST와 PORT를 사용하여 서버에 접속합니다.
client_socket.connect((HOST, PORT))
# 메시지를 전송합니다.
client_socket.sendall('안녕'.encode())
# 메시지를 수신합니다.
data = client_socket.recv(1024)
print('Received', repr(data.decode()))
# 소켓을 닫습니다.
client_socket.close()
# TCP & UDP
TCP와 UDP는 Transprot Layer에서 사용되는 프로토콜이지만, 간략하게 설명을 한다면 주고 받는 데이터들에 대해서 어떤 부가적인 기능을 제공하느냐의 차이다.
- TCP : reliable transport(데이터 손실 방지), flow control(패킷이 섞이지 않게), congestion control(혼잡 제어), connection-oriented( handshake과정을 거쳐 미리 연결한다음 데이터를 주고 받음)
- - UDP : unrelaible data transfer
TCP 와 UDP의 가장 큰 차이점은 , reliable과 connection이다. UDP는 이와 같은 과정이 없기 때문에 속도가 빠르다.
# HTTP
- HyperText Transfer Protocol의 약자이다.
- 웹에서 사용
- stateless이기때문에 과거의 전송에대해서 기억하지 않는다.
- TCP를 사용한다
- non-persistent와 persistent로 커넥션을 유지하는 두개의 방법이 있다.
클라이언트가 request(요청)를 서버에게 보내면, 서버는 request에 대한 response(응답)를 보낸다. 그 요청에는 html, img, object가 될 수도 있고, API서버에서는 DB의 값을 보내준다는지 등등 코드를 짜기 나름이다.
## Non-persistent HTTP
request요청을 보내기전에 서버와 연결을 맺고 request와 response를 주고 받는다. 1개의 request-response쌍이 끝나면 TCP 연결을 close하기 때문에 다시 요청을 보내더라도 위의 과정을 반복한다.
RTT(Round-Trip-Time, 패킷이 1회 왕복하는데 걸리는 시간)가 기본적으로 2번이 될 수 밖에 없다. 즉 응답을 위해서 걸리는 시간인 response time = 2RTT + transmission time이 된다.
## Persistent HTTP
1회의 커넥션을 맺고 close하기 전까지 자유롭게 request와 response를 주고 받는다.
## HTTP request message
각각의 프로토콜 별로 메시지를 보내는 형식이 있다고 했다. HTTP reqeust는 아래와 같다.
프론트이든 백엔드인드 웹을 경험해 봤다면 익숙 할 것이다. 나도 뭔지는 모르고 쓰라길래 썼었는데, 수업 들으면서 알게 됐다.
백엔드를 하다보면
req.header
// or
req.body
와 같은 코드들을 보았을텐데, 이게 바로 저 위에 있는 메시지에서의 값들을 가져오는 것이다.
method에는 POST/GET/HEAD/PUT/DELETE와 같은 것을 넣어보냄으로써 서버에서 이 메시지가 뭐를 요청하는지 한눈에 알 수 있도록 해준다.
HTTP/1.0 , HTTP/1.1과 같은 버전을 적어줘야 한다.
## HTTP response message
응답 메시지를 보낼때는 아래와 같이 약속한 코드를 보내어, 해당 응답이 잘 됐는지를 client에게 알려준다.
- 200 OK
- 301 Moved Permanetly
- 400 Bad Request
- 404 Not Found
- 505 HTTP Version Not supported
## Cookie
HTTP는 stateless라고 했기때문에, 매번 요청들은 독립된 요청이기에 과거의 정보가 없다. 그렇기 때문에 뭔가 기억해야할 요청들이 있다면 쿠키에 담아두게 되면 정해진 시간동안에는 매 요청에 등록된 쿠키가 같이 전송된다.
아마존 웹페이지에 접속한다고 생각해보자. 아마존에 로그인을 하고 난후, 물건을 구매 버튼을 누르더라도, client-server에는 사실 그전에 로그인을 했다는 것은 모른다. 쿠키가 없다면 말이다. 그래서 이렇게 로그인을 했다는 인증자체를 쿠키에 담아두면, 다음 요청때 서버는 쿠키를 읽어서 로그인을 했구나라는 사실을 알게 된다.
이렇게 state를 관리한다.
# 마치며
다음 포스팅에는 프록시서버, SMTP(메일) DNS와 P2P 프로토콜들에 대해서 정리하도록 하겠다. 사실 Application-Layer자체가 네트워크에 최상단에 위치하고, 사용자들이 직접 마주하는 것들이기 때문에 익숙한 측면도 있다. 그리고 각각의 프로토콜의 메시지 타입들만 안다면 쉽게 사용할 수 있다.
정말로 네트워크라고 생각이 드는건 뒤에서 나올 Network-layer와 Data-layer이다. 난 이부분을 더 재밌게 공부했던것 같다. 방학이기에 시간적 압박이 없기 때문에 쫒기지 않고 정리하도록 하겠다.