본문 바로가기
Develop/Network

[윤성우의 열혈 TCP/IP 소켓 프로그래밍] Chapter05 - 내용 확인 문제 풀이

by Tarra 2023. 6. 28.

 

 

 

 

 [윤성우의 열혈 TCP / IP 소켓 프로그래밍] 책을 기반으로 개인적으로  문제 풀이 및 개념을 정리한 내용입니다.

모든 소스 코드와 강의, 확인 문제의 정확한 답안은 (23년 7월 1일부터 전면 무료화 예정)

http://www.orentec.co.kr/

 

====== 오렌지 미디어 ======

 

www.orentec.co.kr

에서 확인할 수 있습니다.

 

 


 

 

01. TCP 소켓의 연결설정 과정인 Three-way handshaking에 대해서 설명해보자. 특히 총 3회의 데이터 송수신이 이뤄지는데, 각각의 데이터 송수신 과정에서 주고 받는 데이터에 포함된 내용이 무엇인지 설명해보자.

 

TCP의 Three-way handshaking은 TCP 소켓간의 연결 설정을 위한 과정이다.

이 과정은 클라이언트와 서버 간에 세 개의 패킷을 주고받으며 진행되는데, 각각의 데이터 송수신 과정에서 주고 받는 데이터에 포함된 내용은 다음과 같다.

 

1. 첫 번째 단계 (SYN)

클라이언트가 서버에 연결을 요청하기 위해 SYN(Synchronize) 패킷을 보낸다.

이 패킷에는 클라이언트의 초기 순서 번호(Sequence Number)가 포함되어 있다.

클라이언트는 이 패킷을 보내고 연결 요청 상태(SYN_SENT)로 전환된다.

 

2. 두 번째 단계 (SYN-ACK) 

서버는 클라이언트의 연결 요청을 받으면 SYN-ACK(Synchronize-Acknowledgment) 패킷을 보낸다.

이 패킷에는 서버의 초기 순서 번호와 클라이언트의 순서 번호에 1을 더한 값(ACK Number)이 포함된다.

서버는 이 패킷을 보내고 연결 요청을 받아들인 상태 (SYN_RCVD)로 전환된다.

 

3. 세 번째 단계 (ACK)

클라이언트는 서버의 SYN-ACK 패킷을 받으면 ACK(Acknowledgment) 패킷을 보낸다.

이 패킷에는 서버의 ACK Number가 포함되어 있다. 클라이언트는 이 패킷을 보내고 연결 설정이 완료된 상태로 전환된다.

서버는 이 ACK 패킷을 받으면 연결 설정이 완료된 상태로 전환된다.

 

위와 같은 세 번의 데이터 송수신 과정을 통해 클라이언트와 서버는 상호간의 초기 순서 번호 및 연결에 필요한 정보를 교환하고, 신뢰성 있는 연결을 설정한다. 이후에는 데이터를 안정적으로 주고받을 수 있는 TCP 연결이 확립된다.

 

더보기

모범 답안

먼저 호스트 A가 호스트 B에게 전달하는 메시지를 가리켜 SYN이라 한다. 이렇듯 호스트 A가 호스트 B에게 전송하는 데이터의 동기화를 위해서 처음 보내는 '동기화 메시지'를 가리켜 SYN이라 한다.

 

이어서 호스트 B가 호스트 A에게 전달하는 메시지를 가리켜 SYN-ACK라 한다. 이는 처음 보내는 동기화 메시지와 앞서 수신한 메시지에 대한 응답의 내용까지 포함되어 있기 때문이다.

 

그리고 마지막으로 호스트 A가 호스트 B에게 전달하는 메시지에는 동기화 정보가 포함되어 있기 때문에 ACK라 한다.

 

 

 

02. TCP는 데이터의 전송을 보장하는 프로토콜이다. 그러나 인터넷을 통해서 전송되는 데이터는 소멸될 수 있다. 그렇다면 TCP는 어떠한 원리로 중간에 소멸되는 데이터의 전송까지 보장을 하는 것인지 ACK와 SEQ를 대상으로 설명해보자.

 

ACK(Acknowledgment)와 SEQ(Sequencd Number)는 신뢰성을 구현하는데 중요한 역할을 한다.

 

ACK는 수신측에서 송신측으로 전송된 데이터를 확인하고 응답하는 메커니즘이다.

수신측은 정상적으로 받은 데이터의 ACK를 송신측으로 전송함으로써 데이터의 수신 확인을 알린다.

ACK를 받은 송신측은 해당 데이터가 정상적으로 도달했다고 판단하고 다음 데이터를 전송한다.

ACK번호는 수신한 데이터의 마지막 바이트 순서 번호를 의미하게 된다.

 

SEQ는 TCP 세그먼트(데이터 패킷)에 부여된 일련 번호이다. 송신측은 전송하는 데이터 세그먼트마다 일련번호를 부여하여 데이터의 순서를 지정한다. 수신측은 SEQ 번호를 통해 데이터의 순서를 확인하고, 필요한 경우 재조립하거나 순서대로 전달한다.

 

TCP는 송신측이 데이터를 전송할 때, 수신측이 ACK를 받아야만 다음 데이터를 전송하도록 설계되어 있다.

만약 ACK를 받지 못한 경우, 송신측은 해당 데이터를 재전송하게 된다. 이를 통해 데이터의 손실이나 소멸을 감지하고 복구하는 기능을 제공한다.

 

더보기

모범 답안

SEQ는 메시지에 번호를 부여하는데 사용된다. 반면 ACK는 번호가 부여된 메시지의 응답에 사용된다.

즉, 메시지를 보낼 때마다 SEQ 정보를 함께 보내는데, 이를 수신한 호스트는 이를 전송한 호스트에게 SEQ 정보를 바탕으로 ACK 메시지를 보내야 한다.

이러한 기본적인 형태로 데이터의 송수신을 확인하기 때문에 데이터를 전송한 호스트는 데이터의 전송여부를 확인할 수 있다.

따라서 데이터의 전송이 실패하는 경우에는 재전송을 진행할 수 있다.

 

 

03. TCP 소켓을 기반으로 write 함수와 read 함수가 호출되었을 때의 데이터 이동을 입력버퍼와 출력버퍼의 상태와 더불어서 설명해보자.

 

1. write 함수 호출

- 클라이언트는 write 함수를 호출하여 데이터를 TCP 소켓에 기록한다.

- 클라이언트의 데이터는 출력 버퍼에 저장된다.

- 출력 버퍼는 소켓의 내부 버퍼로서, 클라이언트의 데이터를 임시로 저장한다.

- 출력 버퍼는 네트워크로 데이터를 전송하기 위해 사용된다.

 

2. 데이터 전송

- 출력 버퍼에 저장된 데이터는 TCP 프로토콜에 의해 패킷으로 분할되고 네트워크로 전송된다.

- TCP는 안정적이고 신뢰성 있는 데이터 전송을 위해 패킷을 세그먼트로 분할하고, 서버에서의 재조립을 지원한다.

- 네트워크로 전송된 패킷은 서버로 전달된다.

 

3. read 함수 호출

- 서버는 read 함수를 호출하여 수신 대기 상태에 들어간다.

- 네트워크로부터 도착한 패킷은 TCP 프로토콜에 의해 수신자의 입력 버퍼로 전달된다.

- 입력 버퍼는 소켓의 내부 버퍼로서, 수신자의 데이터를 임시로 저장한다.

- 입력 버퍼에서 데이터를 읽기 전까지 데이터는 입력 버퍼에 유지된다.

 

4. 데이터 수신

- 입력 버퍼에 저장된 데이터는 read 함수를 통해 서버에게 제공된다.

- 서버는 read 함수를 호출하여 입력 버퍼에서 데이터를 읽는다.

- 읽은 데이터는 서버의 프로그램으로 전달되어 처리된다.

- 처리된 데이터는 서버의 프로그램에 따라 적절한 응답이 이루어진다.

 

입력 버퍼와 출력 버퍼는 소켓의 내부 버퍼로서, 데이터의 송수신을 임시로 저장하고 처리하기 위해 사용된다.

출력 버퍼는 클라이언트에서 데이터를 기록하고, 입력 버퍼는 서버에서 데이터를 읽어들인다.

데이터는 버퍼를 거쳐 전송되며, 버퍼의 크기에 따라 데이터의 임시 저장 및 처리 여부가 결정된다.

 

더보기

모범 답안

write 함수가 호출되는 순간 데이터는 소켓의 출력 버퍼로 이동이 된다.

그리고 이렇게 이동이 된 데이터는 TCP 프로토콜을 기반으로 상대방 호스트 소켓의 입력버퍼로 전송이 되며, 이렇게 해서 입력 버퍼에 저장된 데이터는 read 함수의 호출을 통해 읽혀지게 된다.

 

 

04. 데이터를 수신할 상대 호스트의 입력버퍼에 남아있는 여유공간이 50byte인 상황에서 write 함수호출을 통해서 70byte의 데이터 전송을 요청했을 때, TCP는 어떻게 이를 처리하는지 설명해보자.

 

TCP는 데이터의 전송을 보장하고 신뢰성을 제공하기 위해 흐름 제어(flow control) 메커니즘을 사용한다.

흐름 제어는 클라이언트와 서버 사이에서 데이터의 전송 속도를 조절하여 수신 버퍼의 오버플로우를 방지하고 데이터의 손실을 최소화한다.

 

데이터를 수신할 상대 호스트의 입력 버퍼에 여유 공간이 50바이트인 상황에서 70바이트의 데이터를 전송하려고 할 때, 다음과 같은 과정이 이루어진다.

 

1. 클라이언트는 write 함수를 호출하여 70바이트의 데이터를 TCP 소켓에 기록한다.

2. 클라이언트의 출력 버퍼에 데이터가 저장된다.

3. TCP는 서버로부터 수신 버퍼의 여유 공간을 확인하기 위해 ACK(수신 확인 응답) 메시지를 서버에게 전송한다.

4. 서버는 ACK 메시지를 통해 수신 버퍼의 여유 공간을 클라이언트에게 알려준다.

5. 클라이언트는 수신자의 ACK 메시지를 수신하여 수신 버퍼의 여유 공간을 확인한다.

6. 클라이언트느 ㄴ수신 버퍼의 여유 공간이 50바이트 이하인 것을 감지하고, 해당 데이터 중 50바이트만 전송한다.

7. 전송된 50바이트의 데이터는 수신자의 입력 버퍼에 저장된다.

8. 남은 20바이트의 데이터는 클라이언트의 출력 버퍼에 남아있따.

9. 서버는 입력 버퍼의 여유 공간을 다시 확인하기 위해 ACK 메시지를 클라이언트에게 전송한다.

10. 클라이언트는 서버의 ACK 메시지를 수신하여 입력 버퍼의 여유 공간이 생겼다는 것을 확인한다.

11. 클라이언트는 남은 20바이트의 데이터를 추가로 전송한다.

12. 전송된 20바이트의 데이터는 서버의 입력 버퍼에 추가로 저장된다.

 

더보기

모범 답안

수신할 상대 호스트의 입력버퍼에 저장 가능한 데이터 크기는 데이터를 전송하는 호스트에게 전달된다.

따라서 여유공간이 50바이트인 상황에서는 70바이트의 데이터 전송이 요청되더라도, 50바이트 이상 전송이 이뤄지지 않는다.

나머지는 전송 측의 출력버퍼에 저장된 상태에서 상대 호스트의 입력 버퍼에 여유가 생기기를 기다리게 된다.

그리고 이렇게 버퍼의 여유 공간 정보를 교환하는 프로토콜을 가리켜 '슬라이딩 윈도우'라 하며,

이 역시 TCP의 일부분으로 존재하는 프로토콜이다.

 

 

05. Chapter 02에서 보인 예제 tcp_server.c(Chapter 01의 hello_server.c)와 tcp_client.c에서는 서버가 전송하는 문자열을 클라이언트가 수신하고 끝낸다. 그런데 이번에는 서버와 클라이언트가 한번씩 문자열을 주고 받는 형태로 예제를 변경해보자. 단! 데이터의 송수신이 TCP를 기반으로 진행된다는 사실을 고려하여 문자열 전송에 앞서 문자열의 길이 정보를 4바이트 정수의 형태로 먼저 전송하기로 하자. 즉 연결이 된 상태에서 서버와 클라이언트는 다음의 유형으로 데이터를 송수신해야 한다. 그리고 문자열의 전송순서는 상관이 없으며 문자열의 종류도 여러분이 임의로 결정해도 된다. 단, 총 3회 문자열을 주고받아야 한다.

 

(생략)

 

 

06. 파일을 송수신하기 위한 클라이언트와 서버를 구현하되, 다음 순서의 시나리오를 기준으로 구현해보자.

- 클라이언트는 프로그램 사용자로부터 전송 받을 파일의 이름을 입력받는다.

- 클라이언트는 해당 이름의 파일전송을 서버에게 요청한다.

- 파일이 존재할 경우 서버는 파일을 저장하고, 파일이 존재하지 않을 경우 그냥 연결을 종료한다.

 

(생략)

 

 


출처 : [윤성우의 열혈 TCP / IP 소켓 프로그래밍] / 윤성우 저 / 오렌지 미디어

https://cafe.naver.com/cstudyjava

 

윤성우의 프로그래밍 스터디그룹 [C/... : 네이버 카페

윤성우의 스터디 공간입니다. C와 JAVA를 공부하시는 분들은 모두 들어오세요. ^^

cafe.naver.com