accept() 함수는 연결지향 소켓 타입 (SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM)에 사용된다.
이것은 아직 처리되지 않은 연결들이 대기하고 있는 큐에서 제일 처음
연결된 연결을 가져와서 새로운 연결된 소켓을 만든다. 그리고 소켓을
가르키는 파일 지정자를 할당하고 이것을 리턴한다.
인자 s 는 socket() 로 만들어진
end-point(듣기 소켓)을 위한 파일지정자이다.
인자 addr 는 sockaddr 구조체에 대한 포인터이다.
연결이 성공되면 이 구조체를 채워서 되돌려 주게 되고, 우리는 이구조체의
정보를 이용해서 연결된 클라이언트의 인터넷 정보를 알아낼수 있다.
addrlen 인자는 addr의 크기
이다.
만약 미결인 연결이 큐에 존재하지 않고, 소켓이 비봉쇄가 아니라면
accept 는 연결이 존재할때까지 해당영역에서 봉쇄된다.
비봉쇄 소켓일경우에는 errno 로 EAGAIN 을 설정하고 바로 리턴한다.
#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 을 입력하면 된다.
1장. accept(2)
소켓에 연결을 받아들인다.
1.1절. 사용법
1.2절. 설명
accept() 함수는 연결지향 소켓 타입 (SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM)에 사용된다. 이것은 아직 처리되지 않은 연결들이 대기하고 있는 큐에서 제일 처음 연결된 연결을 가져와서 새로운 연결된 소켓을 만든다. 그리고 소켓을 가르키는 파일 지정자를 할당하고 이것을 리턴한다.
인자 s 는 socket() 로 만들어진 end-point(듣기 소켓)을 위한 파일지정자이다.
인자 addr 는 sockaddr 구조체에 대한 포인터이다. 연결이 성공되면 이 구조체를 채워서 되돌려 주게 되고, 우리는 이구조체의 정보를 이용해서 연결된 클라이언트의 인터넷 정보를 알아낼수 있다. addrlen 인자는 addr의 크기 이다.
만약 미결인 연결이 큐에 존재하지 않고, 소켓이 비봉쇄가 아니라면 accept 는 연결이 존재할때까지 해당영역에서 봉쇄된다. 비봉쇄 소켓일경우에는 errno 로 EAGAIN 을 설정하고 바로 리턴한다.
1.3절. 반환값
에러시 -1이 반환된다. 성공한다면 받아들인 소켓을 위한 파일지정번호 (0보다 큰)을 반환한다.
1.4절. 예제
Recent Posts
Archive Posts
Tags