Network/소켓통신(Linux)

TCP 동작 과정 및 함수 정리

busy맨 2023. 11. 19. 18:05

1. TCP 서버 함수

1) 서버 함수 동작

  1. socket() 함수로 소켓을 생성함으로써 사용할 프로토콜을 결정
  2. bind() 함수로 소켓을 지역 IP 주소와 지역 포트 번호를 결정
  3. listen() 함수로 소켓의 TCP 함수를 LISTENING으로 변경
  4. accept() 함수로 클라이언트 접속을 수용하고, 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성
    이때, 원격 IP 주소와 원격 포트 번호가 결정
  5. send() 함수와 recv() 함수 등의 데이터 전송 함수로 클라이언트와 통신을 수행한 후 close() 함수로 소켓을 종료
  6. 새로운 클라이언트 접속이 들어올 때마다 4~5 동작을 반복

2) bind() 함수

  • 소켓의 지역 IP 주소와 지역 포트 번호를 결정
#include<sys/types.h>
#include<sys/socket.h>

int bind(
	int sock,
    	const struct sockaddr *addr,
    	socklen_t addrlen
);
  • sock
    • 클라이언트 접속을 수용하는 소켓으로, 지역 IP 주소와 지역 포트 번호가 아직 결정 되지 않은 상태
  • addr
    • 소켓 주소 구조체로, 통신 프로토콜에 따른 주소 정보를 담고 있음
    • TCP/IP의 경우 sockaddr_in 또는 sockaddr_in6 구조체를 사용하되, 지역 IP 주소와 지역 포트 번호로 초기화하여 전달
  • addrlen
    • 소켓 주소 구조체의 길이(바이트 단위)

3) listen() 함수

  • 소켓의 TCP 상태를 LISTENING으로 바꿈
    • 클라이언트 접속을 받아 들일 수 있는 상태를 의미
#include<sys/types.h>
#include<sys/socket.h>

int listen(
	int sock,
    	int backlog
);
  • sock
    • 클라이언트 접속을 수용하는 소켓으로, bind() 를 호출하여 지역 IP 주소와 지역 포트 번호를 설정한 상태
  • backlog
    • 서버가 당장 처리하지 않더라도 접속 가능한 클라이언트의 개수
    • 클라이언트의 접속 정보는 연결 큐(Connection Queue)에 저장되는데, backlog는 연결 큐의 길이를 의미

4) accept() 함수

  • 클라이언트 접속을 수용하고, 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성하여 리턴
  • 접속한 클라이언트의 주소 정보도 함수 인수를 통해 얻음
    • 서버 입장에서는 원격 IP 주소와 원격 포트 번호
    • 클라이언트 입장에서는 지역 IP 주소와 지역 포트 번호
  • 클라이언트가 접속했다는 것은 TCP 프로토콜 수준에서 연결 설정이 성공적으로 이루어졌다는 것을 의미
#include<sys/types.h>
#include<sys/socket.h>

int accept(
	int sock,
    	struct sockaddr *addr,
        socklen_t *addrlen
);
  • sock
    • 클라이언트 접속을 수용하는 소켓
    • bind()로 지역 IP주소와 지역 포트 번호를 설정하고, listen()으로 TCP 상태를 LISTENING으로 변경한 상태
  • addr
    • 소켓 주소 구조체를 전달하면, 접속한 클라이언트의 주소 정보로 채워짐
      • 주소정보 = IP 주소 +  포트 번호
  • addrlen
    • addr이 가리키는 소켓 주소 구조체의 크기로 초기화하여 전달
    • accept() 함수가 리턴하면 *addrlen에는 주소 정보의 크기(바이트 단위)가 저장

 

2. TCP 클라이언트 함수

1) TCP 클라이언트 함수 동작

  1. socket() 함수로 소켓을 생성함으로써 사용할 프로토콜을 결정
  2. connect() 함수로 서버에 접속
    이때, 원격 IP 주소와 원격 포트 번호, 지역 IP 주소와 지역 포트 번호도 결정됨
  3. send(), recv() 함수 등의 데이터 전송 함수로 서버와 통신한 후 close() 함수로 소켓을 닫음

2) connect() 함수

  • TCP 프로토콜 수준에서 서버와 논리적 연결을 설정
  • 클라이언트는 서버와 달리 bind()함수를 호출하지 않음
    • 운영체제가 자동으로 지역 IP 주소와 지역 포트 번호를 할당해주기 때문에
#include<sys/types.h>
#include<sys/socket.h>

int connect(
	int sock,
    	const struct sockaddr *addr,
        socklen_t *addrlen
);

3) send()

  • 응용 프로그램의 데이터 전송을 위해 운영체제의 송신 버퍼에 데이터를 복사하고 곧바로 리턴
  • send() 함수가 리턴했다고 실제 데이터가 전송된 것은 아니며, 일정 시간이 흘러야 TCP/IP를 통해 전송이 완료
#include<sys/types.h>
#include<sys/socket.h>

ssize_t send(
	int sock,
    	const void *buf,
        size_t len,
        int flags
);
  • sock
    • 통신할 대상(서버)과 연결된 소켓
  • buf
    • 보낼 데이터를 담고 있는 응용 프로그램 버퍼의 주소
  • len
    • 보낼 데이터의 크기(바이트 단위)
  • flags
    • send() 함수의 동작을 바꾸는 옵션으로, 거의 항상 0을 사용

4) recv() 함수

  • 운영체제의 수신 버퍼에 도착한 데이터를 응용 프로그램 버퍼에 복사
  • 수신 버퍼에 데이터가 도달한 경우, 데이터를 응용 프로그램 버퍼에 최대한 복사한 후 실제 복사한 바이트 수를 리턴
    • recv()의 리턴값은 최소 1, 최대 len
  • TCP 프로토콜 수준에서 정상적인 접속 종료를 위한 패킷 교환 절차가 일어나는데, 이 경우 0을 리턴
#include<sys/types.h>
#include<sys/socket.h>

ssize_t recv(
	int sock,
    	void *buf,
        size_t len,
        int flags
);
  • sock
    • 통신할 대상(서버)과 연결된 소켓
  • buf
    • 받은 데이터를 저장할 응용 프로그램 버퍼의 주소
  • len
    • 운영체제의 수신 버퍼로부터 복사할 최대 데이터 크기(바이트 단위)
    • buf가 가리키는 응용 프로그램 버퍼보다 값이 크지 않아야함
  • flags
    • recv() 함수의 동작을 바꾸는 옵션

'Network > 소켓통신(Linux)' 카테고리의 다른 글

멀티스레드: 리눅스 1  (1) 2023.11.19
멀티스레드 개념  (2) 2023.11.19
데이터 전송하기  (0) 2023.09.17
TCP 서버 - 클라이언트 구조  (2) 2023.09.02
23.03.09) TCP/IP 소켓 프로그래밍(Linux) 2  (0) 2023.03.09