메뉴

문서정보

accept - 소켓으로 부터 연결을 받아들인다.

<a href="/modules/moniwiki/wiki.php/manSearch?google=none&name=accept">accept</a>(2)

1장. accept(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 예제

소켓에 연결을 받아들인다.


1.1절. 사용법

#include <sys/types.h>

#include <sys/socket.h>

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
		


1.2절. 설명

accept() 함수는 연결지향 소켓 타입 (SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM)에 사용된다. 이것은 아직 처리되지 않은 연결들이 대기하고 있는 큐에서 제일 처음 연결된 연결을 가져와서 새로운 연결된 소켓을 만든다. 그리고 소켓을 가르키는 파일 지정자를 할당하고 이것을 리턴한다.

인자 ssocket() 로 만들어진 end-point(듣기 소켓)을 위한 파일지정자이다.

인자 addr 는 sockaddr 구조체에 대한 포인터이다. 연결이 성공되면 이 구조체를 채워서 되돌려 주게 되고, 우리는 이구조체의 정보를 이용해서 연결된 클라이언트의 인터넷 정보를 알아낼수 있다. addrlen 인자는 addr의 크기 이다.

만약 미결인 연결이 큐에 존재하지 않고, 소켓이 비봉쇄가 아니라면 accept 는 연결이 존재할때까지 해당영역에서 봉쇄된다. 비봉쇄 소켓일경우에는 errno 로 EAGAIN 을 설정하고 바로 리턴한다.


1.3절. 반환값

에러시 -1이 반환된다. 성공한다면 받아들인 소켓을 위한 파일지정번호 (0보다 큰)을 반환한다.


1.4절. 예제

#include <sys/types.h>

#include <stdio.h>
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>

#include <arpa/inet.h>
#include <fcntl.h>

#define SA    struct sockaddr

int main(int argc, char **argv)
{
    int i, maxi, sockfd;
    int nread;
    int state = 0;
    int port;
    int n;
    int fd;
    int clilen;

    char buf_out[1024];
    char buf_in[1024];
    char *header;

    int server_sockfd, client_sockfd;

    struct sockaddr_in clientaddr, serveraddr;

    // socket 함수를 이용해서 end-point 소켓을 
    // 만든다.
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);    
    bzero(&serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(8080);

    // 소켓특성을 묶어준다. 
    bind (server_sockfd, (SA *)&serveraddr, sizeof(serveraddr));
    if ((state = listen(server_sockfd, 5)) == -1)
    {
        perror("listen error : ");
        exit;
    }

    header = "HTTP/1.1 200 OK\n"
    "Date: Fri, 01 Feb 2002 01:34:56 GMT\n"
    "Server: Apache/1.3.19 (Unix) PHP/4.0.6\n"
    "X-Powered-By: PHP/4.0.6\n"
    "Connection: close\n"
    "Content-Type: text/html\n\n";

    while(1)
    {
        clilen = sizeof(clientaddr);

        // socket() 함수를 이용해서 만들어진 end-point 소켓지정번호인 
        // server_sockfd 에 연결이 들어오는지를 기다린다.  
        if ((client_sockfd = accept(server_sockfd, (SA *)&clientaddr, &clilen)) == -1)
        {
            perror("accept error : ");
            close(client_sockfd);
        }

        fd = open("/root/index.html", O_RDONLY);

        memset(buf_in, 0x00, 1024);
        while ((n = read(client_sockfd, buf_in, 1024)) > 0)
        {
            break;
        }

        printf("ok end\n");
        write(client_sockfd, header, strlen(header)); 

        while ( (n = read(fd, buf_out, 255)) > 0)    
        {
            write(client_sockfd, buf_out, n);
            bzero(buf_out, 0x00, 255);
        }
        close(client_sockfd);
    }
}
		
위의 예제는 간단한 - 단지 text/html 페이지만 제대로 뿌려줄수 있는 - 웹서버이다. 8080 포트로 조정되어 있으니, 컴파일후 실행시키고 mozilla와 같은 웹브라우저를 통해서 테스트 해보길 바란다. 주소창에 http://127.0.0.1:8080 을 입력하면 된다.