здравствуйте, есть код простейшего эхо-сервера:
#ifndef MAX_BUF
#define MAX_BUF 1024
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = sig_usr;
    sigset_t   set;
    sigemptyset(&set);
    sigaddset(&set, SIGKILL);
    sigaddset(&set, SIGCHLD);
    act.sa_mask = set;
    sigaction(SIGKILL, &act, 0);
    sigaction(SIGCHLD, &act, 0);
    //устанавливаем параметры серверного сокета
    struct sockaddr_in server;
    char client_message[MAX_BUF];
    std::fill(client_message,
              client_message + std::size(client_message) - 1,
              0);
    int listen_desc = ::socket(AF_INET , SOCK_STREAM , 0);
    if (listen_desc == -1) {
        std::cout << "Could not create socket\n";
        ::exit(EXIT_FAILURE);
    }
    setnonblock(listen_desc);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 1600 );
    int yes = 1;
    ::setsockopt(listen_desc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    if( ::bind(listen_desc,(struct sockaddr *)&server , sizeof(server)) < 0) {
        //print the error message
        std::cout << "error in bind\n";
        ::exit(EXIT_FAILURE);
    }
    ::listen(listen_desc , 5);
    //клиентский сокет
    int cs{};
    // create epoll instance
    int epfd;
    epfd = epoll_create(5);
    if (epfd == -1) {
        std::cout << "error in epoll_create\n";
    }
    struct epoll_event evlist[count];
    struct epoll_event ev;
    ev.data.fd = listen_desc;
    ev.events = EPOLLIN | EPOLLET;
    if(::epoll_ctl (epfd, EPOLL_CTL_ADD, listen_desc, &ev) == -1) {
        std::cout << "error in epoll_ctl\n";
    }
    while (/*strstr(request, "close") == NULL*/true) {
        int ready = epoll_wait(epfd, evlist, count, -1);
        if(ready == -1) {
            std::cout << "interrupt syscall epoll_wait was occured\n";
            if(errno == EINTR) {
                std::cout << "continue epoll_wait\n";
                continue;
            }
            std::cout<< "error in epoll_wait and exit\n";
            ::exit(1);
        }
        //добавляем новый дескриптор
        for(auto i=0;i<ready; ++i) {
            if ((evlist[i].events & EPOLLERR) ||
                (evlist[i].events & EPOLLHUP) ||
                (!(evlist[i].events & EPOLLIN)))
            {
                //ошибка в epoll или сокет не готов читать
                std::cout << "epoll error\n";
                ::close (evlist[i].data.fd);
                continue;
            }
            //если событие пришло из слушающего дескриптора
            if(evlist[i].data.fd == listen_desc) {
                struct sockaddr_in in_addr;
                socklen_t in_len;
                in_len = sizeof(in_addr);
//                cs = ::accept(listen_desc, (struct sockaddr *) &client,
//                                            (socklen_t*)&c);
                cs = ::accept (listen_desc, (sockaddr*)&in_addr, &in_len);
                if(cs == -1){
                    std::cout<<"error in accept on listen descriptor\n";
                    continue;
                }
                //добавляем полученный дескриптор в ожидающие
                setnonblock(cs);
                ev.data.fd = cs;
                ev.events = EPOLLIN | EPOLLET;
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, cs, &ev) == -1) {
                    std::cout << "error in add descriptor to epoll\n";
                    continue;
                }
            } else {
                char buf[MAX_BUF];
                ::memset(buf, 0, sizeof(buf));
                int byte_count = ::read(evlist[i].data.fd, buf, MAX_BUF);
                if (byte_count == -1) {
                    std::cout << "error in read\n";
                    continue;
                }
                //если клиент закрыл соединение
                else if(byte_count == 0) {
                    if (epoll_ctl(epfd, EPOLL_CTL_DEL, evlist[i].data.fd, &ev) == -1) {
                        std::cout << "error in delete descriptor from epoll\n";
                        continue;
                    }
                    std::cout << "client with descriptor "
                              << evlist[i].data.fd
                              << " close connection\n";
                    ::close(evlist[i].data.fd);
                } else {
                    //печатаем на экран и отправляем обратно пришедшее сообщение
                    std::fill(client_message,
                              client_message + std::size(client_message) - 1,
                              0);
                    ::memcpy(client_message, buf, byte_count);
                    std::cout << client_message;
                    char response[] =
                            // Заголовок.
                            "HTTP/1.1 200 OK \n Content-Type: text/xml;charset=utf-8 \n Content-Length: 256"
                            // Тело HTML страницы.
                            "<!doctype html>"
                            "<html lang=\"en\">"
                            "<head>"
                            "<meta charset=\"UTF-8\">"
                            "<title>Document</title>"
                            "</head>"
                            "<body>"
                            "ваш запрос: <strong>1</strong>"
                            "</body>"
                            "</html>\n";
                        if (::send(evlist[i].data.fd, response/*client_message*/, sizeof(response)/*byte_count*/, 0) == -1) {
                            std::cout << "error in send\n";
                        }
                    //                    //std::cout << buf;
                    //                    if (::send(evlist[i].data.fd, /*response*/client_message, /*sizeof(buf)*/byte_count, 0) == -1) {
                    //                        std::cout << "error in send\n";
                    //                    }
                }
            }
        }
    }
#else
#endif
з.ы. исправил кое-что, теперь сокеты неблокирующие, возвращается html-страница как ответ

