epoll non blocking 상태에서 sendfile 사용하기
글쓴이: enjoylife / 작성시간: 목, 2009/03/19 - 5:44오후
void set_nonblocking(int fd)
{
int opts;
opts=fcntl(fd, F_GETFL);
if (opts < 0)
{
perror("fcntl failed\n");
return;
}
opts = opts | O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts) < 0)
{
perror("fcntl failed\n");
return;
}
return;
}
... 중략 ...
ev.events = EPOLLIN;
ev.data.fd = server_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev);
while (1)
{
num_fd = epoll_wait(epoll_fd, events, MAXEVENTS, 500);
for (i=0; i<num_fd; i++)
{
if(events[i].data.fd == server_fd)
{
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &len);
// set_nonblocking(client_fd);
ev.data.fd = client_fd;
ev.events = EPOLLIN;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);
printf("%d user connect ...\n", ev.data.fd);
}
else if(events[i].events & EPOLLIN)
{
client_fd = events[i].data.fd;
ev.data.fd = client_fd;
ev.events = EPOLLOUT;
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, client_fd, &ev);
printf("recv ...\n");
recv(client_fd, buf, 512, 0);
printf("%s", buf);
}
else if(events[i].events & EPOLLOUT)
{
char sendmsg[1024];
ssize_t offset = 0;
struct stat stat_buf;
int len;
char buf[1024];
int fd = open("a.tar.gz", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "unable to open %s\n", strerror(errno));
exit(1);
}
fstat(fd, &stat_buf);
client_fd = events[i].data.fd;
sprintf(sendmsg, "HTTP/1.1 200 OK\r\ncontent-type: application/x-octetstream\r\ncontent-disposition: attachment; filename=\"a.tar.gz\"\r\ncontent-length: %zd\r\n\r\n", stat_buf.st_size);
send(client_fd, sendmsg, strlen(sendmsg), 0);
/*int opts;
opts=fcntl(fd, F_GETFL);
opts = opts | O_NONBLOCK;
fcntl(fd, F_SETFL, opts);
fcntl(fd, F_SETFD, FD_CLOEXEC);*/
ret = sendfile (client_fd, fd, &offset, stat_buf.st_size);
ev.data.fd = client_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, &ev);
close(fd);
close(client_fd);
printf("send ... size = [%d]\n", ret);
}
}
}epoll을 사용해서 sendfile로 파일 전송을 하려고 합니다.
웹 브라우저로 접속을 하면 다운로드가 시작이 됩니다.
set_nonblocking 설정을 안하면 block 상태에서는 파일이 정상적으로 다운로드가 됩니다.
문제는 set_nonblocking로 non block으로 변경해서 다운로드를 하면 다운로드 전부 다 되는게
아니고 100kb 이하에서 다운로드가 완료가 됩니다. (용량은 매번 조금씩 다릅니다.)
제가 궁금한건 non block상태에서 sendfile을 이용해서 파일 전송을 하고 싶은데 잘못된 점이나
빠진 부분이 있는지 궁금합니다.
setsockopt - TCP_CORK와 open한 파일을 non block으로 설정도 해보았으나 동일합니다.
Forums:


논 블러킹 상황이면
논 블러킹 상황이면 자기가 보낼 수 있는 만큼 - 일어들인 양이 적든, 보낼 수 있는 양이 적든 - 만 보내고 다시 리턴이 됩니다.
따라서 얼마나 보냈는지를 보고 다시 재시도롤 하는 식으로 해서 계속 보내야 됩니다.
블러킹이면 보내지는 이유는 지정한대로 다 보낼때 까지 리턴을 하지 않아서 그렇죠.
댓글 달기