Использование sendfile () для fd, возвращаемого epoll - PullRequest
0 голосов
/ 05 июля 2019

Я пишу простой TCP-сервер для передачи файлов.Сервер использует объекты epoll для мониторинга входящих соединений и данных, и я хотел бы использовать метод sendfile(), чтобы обеспечить более быструю передачу файлов.

Попытка использовать sendfile() для fd, возвращенного epoll_wait() приводит к ошибке 29.

Я могу читать с этого fd с помощью традиционного read() метода, что означает, что fd не поврежден (хотя fstat() на fd возвращает размер 0).

Я прилагаю фрагмент кода только sendfile(), при необходимости могу поделиться всем кодом:

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;
    }
}

Найти 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;
}

Дескриптор подключения:

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() возвращает -1 и значение errno равно 29.

...