I'm writing a simple TCP server for file transfer.
The server uses an epoll objects to monitor incoming connections and data and I would like to use the sendfile()
method in order to allow faster file transfer.
Trying to use sendfile()
on an fd returned by epoll_wait()
results in errno 29.
I'm able to read from this fd using traditional read()
method, which means the fd is not corrupted (Using fstat()
on the fd returns 0 size though).
I'm attaching the code snippet of the sendfile()
alone, if necessary I can share the entire code:
epoll_wait:
while (true) {
int activeFds = epoll_wait(epollfd, events, MAXEVENTS, -1);
if (-1 == activeFds) {
printf("Epoll wait failed %s\n", strerror(errno));
res = false;
goto Exit;
}
res = iterateActiveFds(activeFds, events);
if (false == res) {
goto Exit;
}
}
Find fd:
bool iterateActiveFds(int activeFds, struct epoll_event events[]) {
bool res = true;
int i;
for (i = 0; i < activeFds; ++i) {
if (events[i].data.ptr == &sockFd) {
res = acceptNewConnection(i);
} else {
res = handelIncomingData(i);
}
}
return res;
}
Handle connection:
bool handelIncomingData(int i) {
bool res = true;
/* Handle data send from client */
int* connData = (int*) events[i].data.ptr;
if ((events[i].events & EPOLLHUP) || (events[i].events & EPOLLERR)) {
/* Error occured */
printf("Epoll error occurred\n");
close(*connData);
free(connData);
} else if (EPOLLIN == events[i].events) {
/* Delete the read event */
res = modifyEpoll(epollfd, EPOLL_CTL_DEL, *connData, 0, 0);
if (false == res) {
goto Exit;
}
/* Handle write in a new thread */
//TODO: integrate threadpool
pthread_t thrd;
if (0 != pthread_create(&thrd, NULL, threadMethod, connData)) {
res = false;
}
pthread_join(thrd, NULL);
}
Exit: return res;
}
sendfile():
void* threadMethod(void* connFd) {
int* connData = (int*) connFd;
int fd = *connData;
/* Transfer using sendfile */
struct stat stat_buf;
off_t offset = 0;
fstat(fd, &stat_buf);
int res = sendfile(file, fd, &offset, 10);
printf("res = %d\n", res);
printf("errno = %d\n", errno);
…
Return NULL;
}
sendfile()
returns -1 and errno is set to 29.