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