[Network] TCP 기반 서버 / 클라이언트

2023. 3. 31. 15:46_Study/Network

728x90

#0331 #네트워크프로그래밍

해당 자료는 강의 학습 자료입니다.

🐇¸.•*¨*•¸.•*¨*•¸.•*¨*•¸.•*¨*•


 

Wireshark 를 이용하여 확인

https://www.wireshark.org/download.html

 

Wireshark · Download

Wireshark: The world's most popular network protocol analyzer

www.wireshark.org

 

 

TCP Header

입력한 포트 번호가 TCP Header에 붙는다.

Source port (송신측 포트번호)

- 설정하지 않은 경우, 랜덤 번호로 자동할당된다.

Destination port (수신측 포트번호)

Sequence number

- 전송하는 데이터의 순서를 표시

- 수신측은 데이터의 순서를 파악하고 재조립함.

 

Acknowledgement number

- 데이터를 받은 수신자가 다음 시퀀스 번호를 할당해서 전송

Flags(NS ~ FIN)

- SYN : 연결 시작을 위해 사용

- FIN : 상대방과의 연결 종료를 요청

- PSH : 송수신 데이터가 버퍼에 다 찰 때까지 기다리지 않고 즉시 전송(Push)

 

 

IP Header

ip 역할이 다름: header(ip 주소)를 추가

상대방 ip 주소 + 자신의 ip 주소 같이 전

 

 

 

 

 

 

연결 요청 대기 상태로의 진입

listen() 함수

#include <sys/socket.h>

int listen(int sock, int backlog);
//성공시 0, 실패 시 -1 반환

sock

- 클라이언트 연결요청을 처리하기 위해 대기 상태에 두는 소켓 디스크립터

- 서버 소켓 (리스닝 소켓)

 

backlog (몇개의 client 까지 요청가능?)

- 연결 요청 대기 큐(queue)의 크기

- 큐의 크기가 5로 설정하면, 클라이언트 연결요청을 5개 까지 대기 시킬 수 있음

 

연결 요청도 일종의 데이터 전송이고 이를 받아들이기 위해 하나의 소켓이 필요하다 (SYN 패킷). 이 소켓을 서버소켓, 리스닝 소켓이라고하며 listen() 함수 호출을 통해 리스닝 소켓이 되도록 한다.

 

 

socket.h 파일 확인

 

 

 

PF_INET vs AF_INET 비교

PF (Protocol Family): 프로토콜 체계 중 하나

AF (Address Family): 주소 체계 중 하나

PF_INET과 AF_INET은 같은 상수 값을 가진다. (같은 #define)

 

 

 

서버 : 클라이언트 연결요청 수락

accept()함수

연결요청 정보를 참조하여 클라이언트와 통신을 위한 별도의 소켓을 생성하는데 (sock) 이를 통해 데이터 송수신이 진행된다.

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 성공시 소켓 디스크립터, 실패시 -1 반환

sock : 서버 소켓의 파일 디스크립터 전달

addr : 연결 요청을 한 클라이언트 주소 정보를 담을 변수의 주소,

- accpet() 함수 호출 후 addr 변수에 클라이언트의 주소 정보가 저장

addrlen: : 두 번째 매개변수 addr의 크기(바이트 단위)

- 크기 정보를 addrlen 에 저장한 다음, 변수의 주소 값을 저장

 

 

 

클라이언트의 기본적인 함수 호출 connect()

connect() 함수

 

 

 

서버에는 소켓이 두 개 생성되었다. 서버 소켓, 클라이언트 소켓. 데이터 통신은 accept이후에 새로생긴 소켓을 가지고 통신이 이루어진다.

 

 

 

 

 

Iterative 서버의 구현

 

Iterative 서버

- 여러 클라이언트의 연결 요청 수락을 위해

 

서버가 반복적으로 accept() 함수 호출하여 계속된 클라이언트의 연결 요청을 수락할 수 있다. 그러나 동시에 둘 이상의 클라이언트에게 서비스를 제공할 수 없다.

 

기존 클라이언트 소켓을 close()하고 다른 클라이언트를 accept() 한 순간에 하나의 클라이언트에게만 서비스 제공

 

 

str_len != 0 이 되는 조건이 있는데 0이 될 조건은 client 가 close() 를 호출하는 경우이다.

fgets는 NULL문자를 포함하기 때문에 strcmp와 message[str_len] = 0; 에 널문자를 고려하고 있다.

 

하나의 클라이언트에게만 서비스 수

 

 

client #1이 "q"를 입력하면 연결이 종료

client #2가 server로 부터 메시지를 수신

 

 

 

에코 클라이언트의 문제점

문제점 : 문제의 발생 소지가 있는 코드

 

TCP 데이터 송수신에는 경계가가 존재하지 않는다. 따라서 위의 코드는 한 번의 read() 함수 호출로 앞서 전송 된 문자열 전체를 읽을 수 있다고 가정 서버가 전송한 문자열의 일부분만 읽혀질 수도 있다.

 

전송할 데이터의 크기가 큰 경우

- 운영체제(커널)는 내부적으로 여러 조각으로 나누어서 클라이언트 에게 전송한다. (MTU)

따라서 작은 데이터를 보낼 때는 문제가 없지만 큰 파일을 보낼 때 문제가 생길 수 있다.

 

 

에코 클라이언트의 해결책!: echo_client2.c

 

 

 

TCP 소켓에 존재하는 입출력 버퍼

입출력 버퍼는 TCP 소켓 각각에대해 별도로 존재하며 소켓 생성시 자동으로 생성된다.

소켓을 닫아도 출력버퍼에 남아있는 데이터는 계속해서 전송이 이루어지지만 입력 버퍼에 남아있는 데이터는 소멸되어 버린다. 

 

흐름 제어 기법 (Flow control)

- 송신측과 수신측의 데이터 처리 속도 차이를 해결하기 위한 방법

- 정지-대기(Stop and wait) 기법

- 슬라이딩 윈도우 (Sliding window) 기법

 

Stop-and wait 흐름 제어 기법

- 전송 측이 프레임을 전송한 다음, 각 데이터 프레임에 대한 ACK를 기다린다.

- ACK 프레임이 도착하면 다음 프레임을 전송한다.

 

 

 

슬라이딩 윈도우 (Sliding window)

서로 성능차이를 극복한다.

 

TCP의 동작원리 : 연결 설정 단계

Wireshark 를 통해 확인 가능

 

Client(44838)   Server (9190)  
  --------SYN------->    
  <----SYN+ACK(SEQ=0 ACK=1)--   9190-43838 
  ----ACK(SEQ=1, ACK=1)---->    
  PSH, ACK(6개 글자)------>
(SEQ =1, ACK =1)
SEQ=1+6 = ACK  
  <-------- ACK
(SEQ =1, ACK =7)
1+6(전송바이트수)  

ACK 번호 : 수신된 SEQ + 1

 

 

TCP의 동작원리 : 데이터의 송수신

왜 전송된 바이트 수 만큼 증가?

이전 데이터 까지 잘 받았으니 그 다음 데이터를 보내라는 의미로 데이터 손실 유무를 확인하기 위해서 +1하여 ACK 신호를 보내는 것이다.

 

 

TCP의 동작원리 : 상대 소켓과의 연결 종료

Four-way handshaking (FIN - ACK - FIN - ACK )

데이터의 손실을 막기위해 Four-way handshaking을 사용한다.