LINUX.ORG.RU

Сообщения slesh

 

черный экран при загрузке Ubuntu 10.4

Когда грузился с лайфсиди всё норм показывается. Затем поставил систему на винт, установил видео дрова ATI. Теперь при старте после выбора пунта загрузки, появляется черный экран и висит на протяжении всей загрузки ядра. Затем как тога грузятся иксы, то повидимому переключается к текстовый режим и появляется моргающий курсор. это продолжается еще секунд 5 после чего сразу появляется рабочий стол. Думал grub криво чтото делает. Поставил burg - таже проблема, то ка теперь вместо черного экрана этображается нестертое окно burg. В настройках стоит quiet splash. отключение их не помогает. Уже и не знаю что делать чтобы грузилось всё красиво

Вообще система была поставлена на переносной (USB) винт. Подключал и к компу и к ноуту(у них почти одинаковые видюхи), везде работает нормально, за исключением загрузки которая нигде не работает.

slesh
()

парочка вопросов по сети и epoll

Разбираюсь сейчас с epoll. Для теста навоял простенький echo сервер
Все вопросы по ходу кода (в комментариях)

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>


#define SERVER_ADDR INADDR_ANY
#define SERVER_PORT 12345
#define MAX_EVENTS  100
#define EPOLL_SIZE  100


int SetNonBlocking(int sock)
{
    int ret = -1;
    int opts = fcntl(sock, F_GETFL);

    if (opts >= 0)
    {
        opts = (opts | O_NONBLOCK);
        if (fcntl(sock, F_SETFL, opts) >= 0)
        {
            ret = 0;
        }
    }

    return ret;
}

int main()
{
    int MainSock;
    struct sockaddr_in saddr;
    int x;
    int cnt;
    int len;
    int epfd;
    struct epoll_event ev;
    struct epoll_event events[MAX_EVENTS];
    char buf[256];
    int Work = 1;

    MainSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (MainSock != -1)
    {
        saddr.sin_family = AF_INET;
        saddr.sin_addr.s_addr = SERVER_ADDR;
        saddr.sin_port = htons(SERVER_PORT);
        x = 1;
        setsockopt(MainSock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x));
        if (bind(MainSock, (struct sockaddr*) &saddr, sizeof (struct sockaddr_in)) != -1)
        {
            listen(MainSock, 100);
            // какое желательное значение ставить для EPOLL_SIZE.
            // да и вообще какое максимально возможное?
            // в одних источниках пишется что задается максимальное
            // в других что желаемое (но не предельное)
            if ((epfd = epoll_create(EPOLL_SIZE)) != -1)  
            {
                ev.events = EPOLLIN;
                ev.data.fd = MainSock;
                // какое максимальное кол-во может быть добавлено сокетов?
                // по описанию - неограниченное. Но всё же лимиты должны быть
                // или пока есть память?
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, MainSock, &ev) != -1)
                {
                    while (Work)
                    {
                        // может ли следующий участок вызвать ошибку при большой загруженности
                        // или же он вызывает ошибку только в реально плачевном случае
                        // когда уже ничего не исправишь?
                        if ((cnt = epoll_wait(epfd, events, MAX_EVENTS, -1)) == -1)
                        {
                            Work = 0;
                        }

                        for (x = 0; x < cnt; x++)
                        {
                            if (events[x].data.fd == MainSock) // if new client
                            {
                                ev.data.fd = accept(MainSock, NULL, 0);
                                if (ev.data.fd == -1)
                                {
                                    Work = 0;
                                }
                                else
                                {
                                    SetNonBlocking(ev.data.fd);
                                    // какие желательно обрабатывать события?
                                    // если необходимо сервер только отвечает на запросы клиента 
                                    //(т.е. сам не шлет данные пока их не запросят)
                                    ev.events = EPOLLIN | EPOLLET;

                                    if (epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1)
                                    {
                                        close(ev.data.fd);
                                    }
                                }
                            }
                            else // if clients event
                            {
                                if (events[x].events & EPOLLIN) // if client sended data
                                {
                                    len = recv(events[x].data.fd, buf, 256, 0);
                                    if (len > 0)
                                    {
                                        if (!strncmp(buf, "EXIT", 4))
                                        {
                                            send(events[x].data.fd, "CLOSED\n", 7, 0);
                                            close(events[x].data.fd);
                                            // надо ли тут удалять сокет из epfd (через EPOLL_CTL_DEL)?
                                            // или достаточно просто его закрыть?
                                        }
                                        else if (!strncmp(buf, "TERM", 4))
                                        {
                                            Work = 0;
                                        }
                                        else
                                        {
                                            send(events[x].data.fd, buf, len, 0);
                                        }
                                    }
                                    else // client disconnected
                                    {
                                        close(events[x].data.fd);
                                        // аналогично вышеуказанному вопросу
                                    }
                                }
                                else if (events[x].events & (EPOLLHUP | EPOLLERR)) // if client error
                                {
                                    close(events[x].data.fd);
                                    // аналогично вышеуказанному вопросу
                                }
                            }
                        }
                    }
                }
                close(epfd);
                // должен ли я тут закрывать все сокеты которые были добавлены ранее?
                // или закрытие epfd автоматически вызовет это??
            }
            close(MainSock);
        }
    }

    return 0;
}

И парочка вопросов дополнительных:
1) какое наиболее оптимальное значение для MAX_EVENTS может быть, если учесть что сервер должен обрабатывать много клиентов сразу и много данных передавать (при этом вычисления минимальны)
2) echo сервер это довольно простой вариант, а если требуется более сложные вычисления которые требуют распараллеливание запросов клиентов. т.е. допустим клиент послал запрос, сервер обработал его и ответил. Какая схема многопоточности подойдет? Вообще в голову пришла идея чтобы как только пришли данные от клиента, так сразу запускать поток для обработки или же уже иметь предварительно запущенные потоки которые ожидают вызова? Или же для linux систем чуть по другому всё? При этом fork недопустим в данном случае из-за особенностей обработки данных.
3) что можно еще использовать для увеличения скорости работы с сетью. Помимо TCP_NODELAY
4) появление каких сигналов желательно обрабатывать в данном случае? потому как столкнулся с проблемой - если записать в сокет отключенного клиента, то появляется сигнал об это.
5) как я понял при добавлении сокета в структуре epoll_event поле fd используется для удобства, а на реале я могу в ptr записать адрес структуры, которая более детально описывает клиента?
6) на Windows системах для автоматической проверки соединения использовал функцию WSAIoctl с флагом SIO_KEEPALIVE_VALS, т.е. при не активности клиента автоматически система посылала пустой пакет с данными на который клиент должен был ответить, по прошествии таймауте (если не было ответа) то соединение считалось потеряным. Если подобие такой функции на Linux системах?
7) перед закрытием сокета, надо ли его переводить обратно в блокируемый режим?

slesh
()

RSS подписка на новые темы