while(true)
{
int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (nfds == -1)
std::cout << "[ERROR] nfds error" << std::endl;
for (size_t k = 0; k < nfds; ++k)
{
if(events[k].data.fd == sock)
{
listen_res = listen(events[k].data.fd, 1);
if(listen_res = 1)
{
connection = accept(sock, (struct sockaddr*)&from, &len);
if(connection == -1)
continue;
if (setnonblocking(connection) == -1)
std::cout << "[ERROR] setnonblocking()" << std::endl;
ev.events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLET;
ev.data.fd = connection;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, connection, &ev) == -1)
std::cout << "[ERROR] epoll_ctl(connection) returned an error " << std::endl;
else
std::cout << "[INFO] New Client's IP: " << inet_ntoa(from.sin_addr) << std::endl;
}
}
else
{
if (events[k].events & (EPOLLRDHUP | EPOLLHUP))
{
std::cout << "Disconnect" << std::endl;
ThreadPool.add(task);
close(events[k].data.fd);
epoll_ctl(epollfd, EPOLL_CTL_DEL, events[k].data.fd, &ev);
}
else if (events[k].events & EPOLLIN)
{
do
{
read(events[k].data.fd, &Packet, sizeof(PacketStructure));
do_work(&Packet);
}while(errno != EAGAIN);
}
}
}
}
После определенного количества посланных пакетов (отправляю части файла размером по 128 байт) этот код перестает принимать пакеты от клиента. Как можно решить проблему?
do {
read(events[k].data.fd, &Packet, sizeof(PacketStructure));
do_work(&Packet);
} while(errno != EAGAIN);
Скорей всего проблема в том, что перед вызовом read()
для такой проверки errno
нужно обнулять вручную т.к. read()
как и ни один другой системный вызов этого не делает. В итоге все исполнения цикла кроме первого обрабатывают ровно один пакет, а когда возникает ситуация, что epoll_wait()
возвращает сокет в котором готово два пакета на считывание, при ещё одном вызове epoll_wait()
всё виснет.
Можно также изменить условие на что-то вроде:
ssize_t read_rv;
do {
read_rv = read(events[k].data.fd, &Packet, sizeof(PacketStructure));
do_work(&Packet);
} while(read_rv >= 0 && errno != EAGAIN);
errno=0;
Также из плохого/подозрительного в приведённом куске:
read
'а должен быть контроль ошибок т.к. в противном случае вероятен вечный цикл.read()
из tcp-сокета может корректно вернуть любое количество данных (от одного байта до sizeof(PacketStructure)
). Соответственно при обработке пакета это надо учитывать...sizeof(PacketStructure)
read
'у не самая лучшая идея т.к. размер многих типов данных архитектурно зависимый... Не говоря уже о порядке байт.EPOLLERR
, в epoll_ctl
явно передавать не обязательно. А вот обрабатывать — желательно.Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Я написал код в соответствии с алгоритмом, но результат неверенСогласно алгоритму, мы должны указать размер матрицы и вручную заполнить...
Проблема такова : исполняемый файл готового приложения запускается вместе с консолью позадиПараметр "Run in terminal" снят, приложение создано...
Я хочу клонировать в скрипте GameObject без его появления на сцене(так что Instantiate не подойдёт)