Client-Server Programming Model
- 모든 네트워크 어플리케이션은 client-server model에 기반을 두고 있음
- server는 resource를 관리하고 그 resource를 조작하여 클라이언트에게 어떠한 서비스를 제공함
- client-server 모델의 근본적인 operation은 transaction임(db transaction이랑은 전혀다름)
- client가 서비스가 필요할 때 request를 보냄(transaction 시작)
- 서버가 request를 받고 resource를 조작함
- 서버가 client에게 response를 보내줌(웹 서버가 클라이언트에게 파일 보내주는)
- 클라이언트가 response를 받고 그것을 조작함(렌더링~~)
Networks
Global IP Internet
- TCP/IP는 사실 프로토콜의 집합임. 각각은 다른 기능을 제공함
- IP 프로토콜은 기본적인 네이밍 스킴과 패킷(known as datagrams)을 보낼 수 있는 배송 메커니즘을 제공함
- IP 프로토콜은 기본적으로 패킷이 손실되거나 복제되었을 때에 회복하려는 노력을 전혀 하지 않기에 믿을만 하지는 않음
- UDP(Unreliable Datagram Protocol) 은 IP 프로토콜을 아주 약간 확장한 것으로 패킷을 프로세스에서 프로세스로 전달함. host에서 host가 아닌
- TCP는 IP 프로토콜 위에 뭘 더 얹어서 만든 복잡한 프로토콜로 프로세스 간에 reliable full duplex (bidirectional) 연결을 맺음
Internet Connections
- 인터넷의 클라이언트와 서버는 byte stream을 전송하고 받음으로써 통신하게 되는데 이 때 connection이 필요함
- connection은 프로세스 각각을 연결하고, full-duplex임(data가 양방향으로 동시에 흐를 수 있다는 것)
- 또한 신뢰성이 있음 (source process에서 보낸 byte stream의 순서대로 목적지 프로세스에서 그대로 받아짐)
- socket은 connection의 end point이고, 각각의 socket은 해당하는 socket address를 갖고 있음
- socket address : IP 주소 & port 로 이루어짐
- ephemeral port : 클라이언트 소켓의 포트는 connection request를 만들 때 커널에 의해 포트가 자동으로 설정됨
- connection은 양 끝단의 socket address pair로 고유하게 식별됨
- (cliaddr: cliport, servaddr: servport)

Sockets Interface
- socket interface는 Unix I/O 함수들과 같이 쓰이는 함수의 집합으로 네트워크 어플리케이션을 구성할 때 사용됨
- Unix kernel의 관점에서는 socket은 커뮤니케이션의 endpoint이고 Unix program의 관점에서는 socket은 해당하는 descriptor를 가진 file로 보이게 됨
- socket descriptor를 만들기 위해서 클라이언트와 서버에서 사용하는 함수
- socket 함수에서 반환된 descriptor는 아직 부분적으로만 open 된 것이고 read나 write를 할 준비는 되지 않음
- client 쪽이냐 서버 쪽이냐에 따라 socket open의 과정이 달라짐
- 디폴트로, 커널은 해당 함수에 의해 생성된 descriptors를 클라이언트 쪽에서 쓰이는 active socket이라고 가정함. listen 함수가 호출될 시 server 쪽의 소켓으로 인지함
- 클라이언트는 해당 함수를 호출하면서 서버와의 커넥션을 맺음
- 커넥션이 성공적으로 맺어지고 나면 read와 write를 할 수 있고 커넥션은 socket pair로 나타내어 질 수 있음
- (cliaddr: cliport, servaddr: servport)
- 위의 두 함수를 묶어주는 함수로써 클라이언트가 서버와 커넥션을 맺기 위해 사용하는 함수임
- 커넥션이 성공적으로 맺어질 시, socket descriptor를 반환하게 되고 해당 socket descriptor에 대해 Unix I/O를 이용하여 서버와 통신을 할 수 있음
- server의 socket address를 socket descriptor에 bind 해주는 역할
- 해당 함수를 호출함으로써 서버에서 쓰이는 소켓이라고 커널이 인식하게 됨
- active socket → listening socket 으로 변환, 클라이언트로부터 커넥션 요청을 받을 수 있게 됨
- 서버가 사용할 수 있는 listening descriptor를 반환하게 됨. socket, bind, listen을 wrapping한 함수
- 클라이언트로부터 커넥션 요청이 들어오기를 기다림
- listening descriptor로 요청이 들어오면 클라이언트 socket address 필드에 값을 채워 넣음
- connected descriptor를 반환하게 됨

socket
Client
connect — client 쪽
open_clientfd
Server
bind
listen
open_listenfd
accept
Why the distinction between listening and connected descriptors?
두개의 descriptor를 구분 함으로써 클라이언트 커넥션을 동시에 많이 처리할 수 있는 concurrent server를 만들 수 있음. connection request가 listening descriptor에 도착할 때마다 process를 만드는 식으로. 계속 듣고 있고, 사용할 것은 connected descriptor로 사용한다는 의미인듯