[Linux Socket] Server - Listen() 함수/ Accept() 함수[3]

LISTEN() 함수

바로 들어오지 마시고 대기표 뽑고 기다리세요

클라이언트 요청을 받기 위한 수신 대기 Queue 생성

- 클라이언트 요청을 바로 받지 않고 수신 대기 큐에 PUSH
- 서버가 클라이언트와 연결될 수 있는지 체크 후 연결하기 위해 바로 연결 X
- 대기 큐를 생성하기 전에 클라언트가 연결 요청을 할 경우 오류 발생

 

#include <netdb.h>

int listen(int sockfd, int backlog)

 

1) sockfd

주소 정보를 할당할 소켓의 파일 디스크립터

※ 파일 디스크립터: Linux가 파일을 구분하기 위해 배정한 번호

 

2) backlog

대기 큐의 크기

접속 가능한 클라이언트의 개수( = 연결 큐의 길이 )

 

TCP는 1:1밖에 안되는데 한 서버에 여러 클라이언트가 연결 요청을 하는 상황 발생
연결 큐가 100개 있다는 것 🟰 번호표가 100개 있다는 것
A 은행에서 "지금 모든 창구가 다 상담중입니다. 대기해주세요" 하는 것과 같다.

 

- 성공시 0, 실패 시 -1

 


ACCEPT() 함수

대기표 1번 들어오세요

클라이언트 요청 수락

- 가장 먼저 연결 요청을 시도한 호스트와 통신을 하기 위해 연결 요청 수락

- Listen 함수에 의해 생긴 대기 큐에 클라이언트의 연결 요청 확인

  ➡️ 있는 경우 수락하여 소켓 파일 디스크립터 값 반환

  ➡️ 없는 경우 연결 요청이 발생할 때까지 대기

#include <netdb.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

 

1) sockfd

주소 정보를 할당할 소켓의 파일 디스크립터

2) *addr

클라이언트 주소 정보를 담을 수 있는 변수

2) *addrlen

클라이언트 주소의 크기

 

ACCEPT 함수 호출 결과

- 성공시 0, 실패 시 -1

 


#include <cstdio>
#include <arpa/inet.h>
#include <stdlib.h>
#include <memory.h>
#include <netdb.h>

int main()
{    
    // server
    int server_socket, status;
    struct sockaddr_in server_addr;
    
    // client 요청 수락용
    int accpet_socket;
    struct sockaddr_in accpet_addr;

    // 1. Socket 생성
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);

    if (server_socket == -1) {
    	printf("Server Socket Error");
        exit(1);
    }

    // 2. 주소정보 저장
    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi("9090"));
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 3. 저장된 주소 정보를 소켓에 등록
    status = bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
    
    if (status == -1) {
        printf("Server Bind Error");
        exit(1);
    }
    
    // 4. 소켓을 클라이언트 요청을 수락할 수 있는 상태로 변환
    status = listen(server_socket, 5);
    
    if (status == -1) {
     	printf("Server Listen Error");
        exit(1);
    }
    
    // 5. 클라이언트 요청 수락
    accpet_socket = accept(server_socket, (struct sockaddr*) &accpet_addr, sizeof(accpet_addr));

    if (accpet_socket == -1) {
        fprintf("Server Accept Error");
        exit(1);
    }

    return 0;
}

'Network > Socket' 카테고리의 다른 글

🔖IP 주소 변환 함수  (0) 2023.05.09
🔖SOCKADDR VS SOCKADDR_IN  (0) 2023.05.09
[Linux Socket] Server - bind() 함수[2]  (0) 2023.05.04
🔖 SOCK_STREAM VS SOCK_DGAM  (0) 2023.05.04
[Linux Socket] Server - socket() 함수[1]  (0) 2023.05.03