COMPUTER NETWORKING A Top-Down app 8th

[Network] 2-7. 소켓 프로그래밍 : 네트워크 애플리케이션 생성

patrick-star 2023. 8. 27. 21:27
728x90

지금까지 중요한 네트워크 애플리케이션을 살펴봤다. 이번 절에서는 실제로 어떻게 네트워크 애플리케이션을 작성하는지 알아보자.
일반적인 네트워크 애플리케이션은 clientserver로 구성된다. 두 프로그램을 수행하면 client process, server process가 생성되고 두 프로세스가 소켓으로부터 읽고(read), 소켓쓰기(write)를 통해 서로 통신한다.
네트워크 애플리케이션을 생성할 때 개발자는 클라이언트 프로그램과 서버 프로그램 모두에 대한 코드를 작성해야 한다.

클라이언트-서버 애플리케이션의 형태

1) RFC에서 정의된 표준 프로토콜을 구현하는 애플리케이션 ⇒ 동작을 규정하는 규칙이 알려져 있어서 개방형(open)이라고도 불린다.
2) 개인의 독점적인 네트워크 애플리케이션

이번 절에서는 client-server 애플리케이션을 개발하는데 있어 중요한 문제를 살펴보고 아주 간단한 client-server 애플리케이션을 구현하는 코드를 살펴볼 것이다.

개발 단계에서 결정해야할 내용 중 하나는 애플리케이션이 TCP / UDP중 어떤 것을 사용할 지 선택해야 한다는 내용이다.
각각에 대한 자세한 내용은 3장에서 다룰 것이다.

간단한 UDP 애플리케이션 & 간단한 TCP 애플리케이션을 이용해서 UDP와 TCP 소켓 프로그래밍을 소개한다.
주로 python을 이용한다. python이 중요한 소켓 개념을 보여주기 때문이다.
Java 언어를 사용한 client-server 프로그램에 관심이 있다면 이 책의 보조 웹사이트를 참고하길 바란다. 이 절에있는 java로 된 모든 예제들을 살펴볼 수 있다.

1. UDP를 이용한 소켓 프로그래밍

2.1에서 다른 컴퓨터에서 수행되는 프로세스 간의 통신소켓메시지를 전송함으로써 실행한다고 했다. 각 프로세스는 과 유사하고 소켓은 과 유사하다. 애플리케이션은 집 안의 문에 있고 전송 계층 프로토콜은 문의 반대쪽에 있다

이제 UDP 소켓을 이용한 두 통신 프로세스들 간의 상호작용에 대해서 더 자세히 알아보자.

1) 송신 프로세스가 데이터의 패킷을 소켓을 통해 밖으로 내보내기 전에, UDP를 사용한다면 먼저 패킷에 목적지 주소를 붙여야 한다.
2) 목적지 주소가 붙은 이 패킷은 소켓을 통과한 이후에 해당 주소를 이용해 ⇒ 인터넷을 통해 수신 프로세스에 있는 소켓으로 이동한다.
3) 패킷이 수신 소켓에 도착하면 수신 프로세스는 소켓을 통해 그 패킷을 추출하고 패킷의 내용을 조사해서 적절한 동작을 취한다.

그렇다면 목적지 주소에는 어떤 정보가 들어있을까. 목적지 호스트의 IP 주소와 호스트 내의 소켓을 식별하는 포트 번호(port number)로 구성되어 있다.

좀 더 나아가면, 송신자의 출발지 주소도 패킷에 붙일 수 있다. 하지만, UDP 애플리케이션에서는 출발지 주소를 패킷에 붙이는 코드를 작성하지는 않는다. 이는 하부의 OS가 자동으로 실행한다.

간단한 클라이언트-서버 애플리케이션을 살펴보자.

1. 클라이언트는 키보드로부터 한 줄의 문자(데이터)를 읽고 그 데이터를 서버에 보낸다.
2. 서버는 그 데이터를 수신하고 문자를 대문자로 변환한다.
3. 서버는 수정된 데이터를 클라이언트에 보낸다.
4. 클라이언트는 수정된 데이터를 수신하고 그 줄을 화면에 나타낸다. 
  • UDP 서비스에서 통신하는 클라이언트와 서버의 소켓 관련 주요 활동

중요한 부분만을 강조하기 위해 의도적으로 최소한의 코드만을 제공했다. 서버 포트 번호는 12000으로 선택했다.

  • UDPClient.py

  • UDPServer.py

지금까지 작성한 client와 server 프로그램을 약간 수정하면 UDP 클라이언트-서버 애플리케이션을 개발할 수 있다.

2. TCP 소켓 프로그래밍

TCP는 연결 지향 프로토콜로 client와 server가 서로에게 데이터를 보내기 전에 먼져 TCP 연결을 설정해야 한다.
한쪽은 client 소켓에 연결되고 다른 한 쪽은 server 소켓에 연결된다.

TCP 연결을 생성할 때 client 소켓 주소(IP 주소 + 포트번호)server 소켓 주소(IP 주소 + 포트번호)를 연관시킨다.

TCP 연결을 설정하고 나면 한쪽에서 다른 쪽으로 데이터를 보낼 때 소켓을 통해 데이터를 TCP 연결을 통해 전송하면 된다.
이 부분에서 UDP와 차이가 난다. UDP에서는 서버가 패킷을 소켓에 제공하기 전에 패킷에 목적지 주소를 붙여야 하기 때문이다.

TCP 에서의 client-server 프로그램의 상호작용을 좀 더 자세히 살펴보자.

1) client는 서버와의 접속을 시도
2) server : client의 초기 접속에 대응할 수 있도록 준비
- 이때, TCP 서버는 client가 접속을 시도하기 전에 프로세스를 먼저 수행하고 있음
- 서버 프로그램은 임의의 컴퓨터에서 수행되고 있는 client로 부터 초기 접속을 처리하는 특별한 출입문(특별한 소켓)을 가져야 한다.

3) 서버 프로세스가 수행되면 client 프로세스는 서버와의 TCP 연결을 시도한다.
- client 프로그램에서 TCP 소켓을 생성했기 때문에 가능하다
- 가능한 이유는... client가 TCP 소켓을 생성할 때 서버의 IP 주소와 포트 번호를 명시했기 때문이다.
- 소켓을 생성한 후 client는 3-way handshake를 실행하고 server와 TCP 연결을 설정한다. (이는 전송 계층에서 수행되는 작업이라 client와 server 프로그램은 전혀 인식하지 못한다)

4) 3-way handshake 과정에서 다음과 같은 동작들을 실행한다.

1) client 프로세스가 server 프로세스에 초기 접속을 한다.
2) server 프로세스는 해당 접속에 대해 해당 client에 지정된 새로운 소켓을 생성한다.

애플리케이션 관점에서 보면 client 소켓server 소켓은 서로 파이프(pipe)에 의해 직접 연결된다. 이를 그림으로 표현하면 아래와 같다.

위 그림과 같이 client 프로세스는 자신의 소켓으로 임의의 바이트를 전송할 수 있으며 보낸 순서대로 서버 프로세스가 바이트를 수신할 수 있도록 TCP가 보장한다. 따라서 TCP는 client-server 사이신뢰할 수 있는(reliable) 서비스를 제공한다.

client 프로세스는 소켓으로 바이트를 전송할 수 있고 소켓으로부터 바이트를 수신할 수 도 있다.
server 프로세스도 소켓으로 바이트를 전송할 수 있고 소켓으로부터 바이트를 수신할 수 도 있다.

- TCPClient.py

- TCPServer.py

2개의 호스트에서 각각의 프로그램을 실행해보고 목적에 맞도록 수정해보면서 학습하도록 하자.

- TCP 전송 서비스를 통해 통신하는 client와 server의 주요 소켓 관련 동작