Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060

Зависание порта

14.09.2015, 12:05. Показов 716. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Может ли подвиснуть сокет? а точнее весь порт. То есть чтение из любого нового сокета подключенного к порту перестанет работать.

Запущено 8 потоков где открыто по epoll дескриптору на поток (epoll_create). ОС Debian x64.
Клиентов порядка 150-150 крутиться.

Сегодня сервер завис. Я не присутствовал и не видел что было точно, его ребутнули, но судя по логам, в один момент всех юзеров выкинуло из за отсутствия входящих пакетов от клиентов.

Есть основной поток, в котором в цикле происходит добавление всех подключенных юзеров из очереди в единый массив.

Каждый и потоков сокетов занимается только принятием и отправкой данных.
При принятии пакета он помещается в массив СокетСессион.

Потом раз в 50мс перебор всех юзеров и проверка наличия пакетов. если за 8 секунд не было пакетов то дисконт.

Вообщем после двух суток работы, сервер перестал принимать пакеты, и я точно не знаю не читались ли вообще данные, или что то ещё, но я вижу по логам что все новые клиенты через 8 секунд отключались из за отсутствия пакетов.
Зависание потоков исключено, так как дисконект проходил нормально судя по логам. То есть что бы получить дисконект, сначала должен основной цикл пометить сокет как закрытый, и только потом сокет удаляется уже из потока в котором он слушается. Да собственно и добавление не работало бы.

Пока всё что приходит в голову, это то что по какйо то причине стало невозможно читать данные из сокетов.

Лог выглядет так
Кликните здесь для просмотра всего текста


.... происходит добавление сессий в разные потоки ...

13-09-2015 09:09:05 Debug: SocketSession create
13-09-2015 09:09:05 Debug: SocketThread::NewConnection(34) size(4)
13-09-2015 09:09:05 Debug: Socket onConnect
13-09-2015 09:09:05 Info: SocketThread::NewConnection
13-09-2015 09:09:05 Debug: Socket create (61)
13-09-2015 09:09:05 Debug: SocketSession create
13-09-2015 09:09:05 Debug: SocketThread::NewConnection(61) size(5)
13-09-2015 09:09:05 Debug: Socket onConnect
13-09-2015 09:09:05 Info: SocketThread::NewConnection
13-09-2015 09:09:05 Debug: Socket create (62)
13-09-2015 09:09:05 Debug: SocketSession create
13-09-2015 09:09:05 Debug: SocketThread::NewConnection(62) size(5)
13-09-2015 09:09:05 Debug: Socket onConnect
13-09-2015 09:09:05 Info: SocketThread::NewConnection
13-09-2015 09:09:05 Debug: Socket create (63)
13-09-2015 09:09:05 Debug: SocketSession create
13-09-2015 09:09:05 Debug: SocketThread::NewConnection(63) size(5)
13-09-2015 09:09:05 Debug: Socket onConnect
13-09-2015 09:09:05 Info: SocketThread::NewConnection
13-09-2015 09:09:05 Debug: Socket create (64)
13-09-2015 09:09:05 Debug: SocketSession create
13-09-2015 09:09:05 Debug: SocketThread::NewConnection(64) size(5)

... тут удаление сокетов добавленных ранее ...

... если небыло активности > 8 сек то удаление сокетов ююю

13-09-2015 09:09:14 Debug: SocketThread:eleteSocket(64) size(4)
13-09-2015 09:09:14 Debug: Socket destroy (64)
13-09-2015 09:09:14 Debug: SocketThread:eleteSocket(63) size(4)
13-09-2015 09:09:14 Debug: Socket destroy (63)
13-09-2015 09:09:14 Debug: SocketThread:eleteSocket(62) size(5)
13-09-2015 09:09:14 Debug: Socket destroy (62)
13-09-2015 09:09:14 Debug: SocketThread:eleteSocket(61) size(5)
13-09-2015 09:09:14 Debug: Socket destroy (61)
13-09-2015 09:09:14 Debug: SocketThread:eleteSocket(34) size(4)



Кусок чтения
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
bool Socket::onRead()
{
    if (isClosed())
        return false;
    
    char buf[BUFF_SIZE];
    int32 len = 0;
    int32 readed = 0;
    while( (readed = ::recv(m_socket, &buf[0], BUFF_SIZE, 0)) > 0 )
    {
        m_buf_input.append(&buf[0], readed);
        len += readed;
    }
 
    if (len <= 0) {
        m_server->log(LOG_ERROR, "SocketSession::onData() from socket(%i) len = %i, errno = %i", m_socket, len, errno);
        if (len == 0 || (errno != EWOULDBLOCK && errno != EAGAIN))
            return false;
    }
 
    return m_session->onRead();
}
 
bool SocketSession::onRead()
{
    if (!m_socket || m_socket->isClosed())
        return false;
 
    while (m_socket->getSize() >= PACKET_HEADER_SIZE) {
        Packet* packet = new Packet();
        m_socket->recv((char*)&packet->m_header, PACKET_HEADER_SIZE, true);
        EndianConvert(packet->m_header.m_packet_size);
        EndianConvert(packet->m_header.m_opcode);
        if (packet->getSize() > 0) {
            if (uint32(packet->getSize() + PACKET_HEADER_SIZE) > m_socket->getSize()) {
                delete packet;
                break;
            }
        }
        char buf[packet->getSize() + PACKET_HEADER_SIZE];
        m_socket->recv((char*)&buf[0], (uint32)(packet->getSize() + PACKET_HEADER_SIZE));
        if (packet->getSize() > 0) {
            packet->append((char*)&buf[PACKET_HEADER_SIZE], packet->getSize());
        }
        addPacket(packet);
    }
    return true;
}
 
void SocketSession::addPacket(Packet* packet)
{
    if (packet->getOpcode() >= OPCODE_MAX) {
        m_server->log(LOG_ERROR, "Invalid opcode %u", packet->getOpcode());
        return;
    }
    m_recv_queue.push(packet);
}


То есть в m_recv_queue пакеты не попадают. все три функции обрабатываются в одном потоке.
в m_recv_queue методы push и pop защищены мьютексом. но зависание точно не там, ибо оно работало несколько месяцев, а потом в в течении нескольких десятков минут ни один пакет не попал в очередь.

то есть всё это время коннектились новые клиенты и не один пакет не прошел.

Всё что приходит в голову
C++
1
if (len == 0 || (errno != EWOULDBLOCK && errno != EAGAIN))
это то что сокеты валились все с ошибкой EAGAIN

Может ли как то зависнуть порт.

Добавлено через 12 часов 9 минут
Может это как то быть связанно с таким закрытием сокета?

C++
1
2
    shutdown(m_socket, SHUT_RDWR);
close(m_socket);
То есть я вызываю shutdown для чтения и записи, возможно ли что в буфере ОС остались данные, и при закрытии каждого сокета они забили буфер?

Хотя вряд ли... клиенты то разные, и когда с тем же номером дескриптора клиент новый подключается, ошибок же нет, что данные не те пришли в начале сессии...
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.09.2015, 12:05
Ответы с готовыми решениями:

Зависание программы из-за COM порта
Всем добрый день! Подскажите, пожалуйста, почему же зависает программа, считывающая данные по COM порту? Программу написал в...

QSerial и зависание COM порта
Доброго времени суток форумчане. Понадобилось тут для отладки сделать простенькую прогу которая по СОМ-порту принимает поток данных и...

Чтение из COM порта, При чтении из порта зависает read()
Каждому рано или поздно приходится программировать com порт. Вот и мой черед пришол. Я ужу умею: Откривать,закривать, писать. а читать не...

4
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,456
16.09.2015, 09:46
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
Кусок чтения
не совсем понятна реакция системы на штатное закрытие сокета после передачи данных - в len будет значение больше нуля, recv вернет ноль и сокет фактически будет мертвым
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
Может это как то быть связанно с таким закрытием сокета?
если так закрывается сокет полученый через акцепт, то на сокет-сервер это не должно влиять
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
возможно ли что в буфере ОС остались данные, и при закрытии каждого сокета они забили буфер?
брррр..

Добавлено через 1 минуту
...как вариант - по каким-то причинам ОС исчерпала запас сокетов и/или соединений и все сокеты отвалились

Добавлено через 1 минуту
..а вообще надо бы знать точно какой кусок кода умер
1
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
16.09.2015, 12:27  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
не совсем понятна реакция системы на штатное закрытие сокета после передачи данных - в len будет значение больше нуля, recv вернет ноль и сокет фактически будет мертвым
штатного нет, там флешка в браузере, она всегда просто рвёт конект. иногда бывает так что отвалился интернет или сеть тогда просто висит, для этого пинг пакет и сделал.

а можно поподробней про штатное закрытие.
Цитата Сообщение от vxg Посмотреть сообщение
recv вернет ноль
там же проверка в 17 строке в коде len == 0 || ...

Цитата Сообщение от vxg Посмотреть сообщение
..а вообще надо бы знать точно какой кусок кода умер
вот этого я как раз и не знаю. вообщем наверное нужно ждать будет ли ещё когда то такое. я добавил вывод логов ещё в нескольких местах.

Цитата Сообщение от vxg Посмотреть сообщение
по каким-то причинам ОС исчерпала запас сокетов и/или соединений
вот это мне как раз и интересно.
всё что я знаю, это акцепт 100% срабатывает и дескриптор сокетов по логам вижно в сокбочках
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
Socket create (64)
64 это как раз дескриптор
дальше он попадает в
C++
1
m_ev.data.fd = m_socket
C++
1
epoll_ctl(m_epfd, EPOLL_CTL_ADD, m_socket, &m_ev)
при закрытии
C++
1
epoll_ctl(m_epfd, EPOLL_CTL_DEL, m_socket, &m_ev)
C++
1
2
shutdown(m_socket, SHUT_RDWR);
::close(m_socket);
вроде бы всё...

epfd в каждом потоке свой. а для слущающего сокета в мейт потоке свой.
C++
1
m_epfd = epoll_create(MAX_CLIENTS_THREAD);
константа равна 1000.
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,456
16.09.2015, 13:52
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
а можно поподробней про штатное закрытие
Цитата Сообщение от DrobyshevAlex Посмотреть сообщение
там же проверка в 17 строке в коде len == 0 || ..
длина не будет нулевой - сокет честно передал данные и только потом закрылся. это все равно что вы делаете шутдаун и клоз только с той стороны.
с epoll не работал может в нем загадка...
1
1178 / 1128 / 94
Регистрация: 31.05.2012
Сообщений: 3,060
16.09.2015, 13:59  [ТС]
Ну дескрипторы освобождаются, да и закрытия там простого нет как я уже говорил выше, всегда обрыв конекта из за закрытия флеша.
Вообщем буду ждать когда ещё такое произойдёт, может более подробные логи помогут...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.09.2015, 13:59
Помогаю со студенческими работами здесь

Зависание оконного приложения при прослушке порта
private void button1_Click(object sender, EventArgs e) { TcpListener listner = new TcpListener(new...

Зависание ОС
Здравствуйте! Простите, если не сюда пишу. Windows 7 64 bit Professional на ноутбуке. После загрузки Рабочего стола зависает...

Зависание
Поставил флешку с образом виндоус, доходит до экрана где нужно выбрать язык винды и зависает намертво, не видно ни указателя мыши ни клава...

Зависание ПК
Есть следующая проблема: 1) При работе компьютер периодически зависает. При этом тухнет монитор (не всегда), не реагирует клавиатура...

Зависание ОС
Здравствуйте, проблема следующая: - очень медленная работа и отказ большинства приложений в XP. Компьютер не мой, доступен только HDD....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru