소켓 프로그래밍 (Socket Programming)

lsjoon·2024년 2월 28일

Network

목록 보기
7/8
post-thumbnail

소켓 (Socket)


(네트워크) 연결의 종단점
= OS 커널에 구현 되어있는 프로토콜 요소에 대한 추상화된 인터페이스
= 장치 File의 일종

네트워크 소켓


프로그램이 네트워크에서 데이터를 송수신할 수 있도록, 네트워크 환경에 연결할 수 있게 만들어진 연결부

OSI 7 Layer(Open System Interconnection 7 layer)의 네번째 계층인
TCP(Transport Control Protocl) 상에서 동작하는 소켓을 주로 사용
= TCP/IP Socket (TCP Socket)

소켓 프로그래밍(Socket programming)
TCP라는 대상을 추상화시킨 파일(Socket)에 대한 입출력(I/O) 방법론

소켓 인터페이스(Socket Interface)
Network Application 을 만들기 위한 Unix I/O 함수들과 함께 사용되는 함수들의 집합


소켓 프로그래밍 과정

일반적인 과정

  1. 클라이언트에서 socket() 을 생성하고 서버에게 connect() 를 요청
  2. 서버는 socket() 을 생성
    2-1. bind()socket()IPPort 를 매핑
    2-2. 클라이언트의 connect() 요청을 listen() 을 통해 감시
  3. accept() 를 통해 connect 요청을 시도한 클라이언트 측의 IPPort 를 서버의 소켓에 { 튜플 } 형태로 식별자에 매핑 후, return
    = { cliaddr : cliport , servaddr : servport }
  4. 클라이언트는 accept()return 으로 연결 식별자(connfd)를 전달받음
  5. write()read() 를 활용하여 클라이언트의 요청을 처리
  6. 요청이 끝나면 close() 로 연결 해제 및 식별자를 할당 해제

CSAPP에서 다루는 과정

- socket
socket() 함수를 통해 socket 식별자를 생성

  • domain : 소켓이 사용될 주소 체계(Address Family) = IPv4 or IPv6
  • type : 소켓의 타입
    - SOCK_STREAM = 연결 지향형(TCP)
    - SOCK_DGRAM = 데이터그램(UDP)
  • protocol : 사용할 프로토콜 지정
    - TCP = IPPROTO_TCP
    - UDP = IPPROTO_UDP
int socket(int domain, int type, int protocol)

>>> Returns : nonnegative deskriptor if OK, -1 on error

- getaddrinfo
getaddrinfo 함수를 통해 socket 식별자를 생성
소켓 인터페이스와 함께 사용함으로써 특정 IP 프로토콜 버전의존하지 않도록 해줌

struct addrinfo {
	int 			ai_flags;		// 
    int 			ai_family;		// AF_INET = IPv4, AF_INET6 = IPv6
    int 			ai_socketype	// SOCK_STREAM = 리스트가 각 고유의 주소에 대해 자신의 소켓 주소가 연결의 끝점으로 사용될 수 있는 최대 한 개의 addrinfo 구조체로 제한
    int 			ai_protocol;	
    char 			*ai_canoname;	// hostname
    size_t 			ai_addrlen;
    struct sockaddr *ai_addr;
    struct addrinfo	*ai_next
}

int getaddrinfo(const char *host, const char *service,
const struct addrinfo *hints, struct addrinfo **result)

>>> Returns : 0 If OK, nonzero error code on error
  • host : IP
  • service : Port
  • *hints : 선택적으로 사용 가능
    - getadderinfo 가 리턴하는 소켓 주소들의 리스트 전반에 걸쳐 보다 상세한 제어를 제공
  • **result : addrinfo 구조체의 연결리스트를 가리키는 포인터

- getnameinfo
인자인 *sa 로 받은 소켓 주소 구조체를 스트링 타입의 IP 와 Port 로 변환 ( 역참조 )

int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen,
char *service, size_t servlen, int flags)

>>> Returns : 0 if OK, nonzero error code on error

- connect
클라이언트에서 서버와의 연결 요청

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

>>> Returns : 0 if OK, -1 on error

- bind
서버에서 커널에게 addr에 있는 서버의 소켓 주소를 소켓 식별자 sockfd와 연결하도록 요청

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

>>> Returns : 0 if OK, -1 on error

- listen
서버에서 sockfd를 듣기 소켓으로 변경, sockfd 는 클라이언트로부터의 연결 요청 승락 가능

  • backlog : I/O multiplexing 을 위한 인자 ( 1 대 N 연결 )
int listen(int sockfd, int backlog)

>>> Returns : 0 if OK, -1 on error

- accept
서버에서 클라이언트로부터의 연결 요청을 기다림

int accept(int listenfd, struct sockaddr *addr, int *addrlen)

>>> Returns : nonnegative connected descriptor if OK, -1 on error
profile
중요한 것은 꺾여도 그냥 하는 마음

0개의 댓글