The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Broken Pipe в TCL, массовый обрыв коннектов"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Broken Pipe в TCL, массовый обрыв коннектов"  
Сообщение от KeeperR email(ok) on 26-Апр-06, 19:55 
Здравствуйте,

Вообщем, написал я демон для чата, на TCL. Функционально работает замечательно, но вот проблема. Например, если в чате сдит народ, не важно сколько. То в непредсказуемый момент может оборваться соединения, порядка у 40-70% пользователей.
Ошибка, которая возникает при обрыве соединений - broken pipe.
can't flush sock#xxx broken pipe

вот несколько процедур, их части:

proc connection {socket clientAddress clientPort} {
    # Отключаем блокировку сокета
    fconfigure $socket -blocking 0
    
    # Проверка на игнор хост
    if {[array exists ignored_host] && [info exists ignored_host($clientAddress)]} {
        # Хост игнорируется
        catch {close $socket}
                # лишний код убрал
        return 0
    }

        fileevent $socket readable [list read_from_socket $socket $clientAddress]
}

# Процедура чтения информации из сокета
proc read_from_socket { socket clientAddress} {
        
    # Читаем информацию из сокета
    if {[catch {set len [gets $socket data] } err] } {
        close_socket $socket "connection time out"
        return 0
    }


    if {[eof $socket]} {
        close_socket $socket "EOF"
        return 0
    }


    # Если никакой информации в сокет не передано, возвращаемся
    if {$len < 0 } {
        if {[fblocked $socket]} {
            echo "Socket $socket get's len -1, but socket is blocked, continue";
            return 0
        }
        close_socket $socket "EOF, READ EVENT, CONNECTION BROKEN: get's len -1 and socket is unbloked"
        return 0
    }
    

    if {$len == 0} {
        return 0
    }
...
...
...

# Процедура отправки сообщения в сокет
proc out { socket msg nonewline } {
        
    # Читаем информацию из сокета
    if {[catch {set len [gets $socket line] } err] } {
        close_socket $socket "connection time out"
        return 0
    }


    if {[eof $socket]} {
        close_socket $socket "EOF"
        return 0
    }


    # Если сокет сломан
    if {$len < 0 } {
        if {[fblocked $socket] != 1} {
        close_socket $socket "EOF, WRITE EVENT, CONNECTION BROKEN: get's len -1 and socket is unbloked"
        return 0
        }
    }

    # Посылаем сообщение в сокет, если происходит ошибка, то убием сокет
        if { [ catch {
        if {$nonewline == 1} {
            puts -nonewline $socket $msg
            } else {
                puts $socket $msg
                }
                flush $socket
                } err ] } {
            #Убиваем сокет
            close_socket $socket "broken pipe"
                        return 0
                        }
        return 0
}

#
# Это в теле скрипта
#

catch {socket -server connection -myaddr $host $port}

Собственно, вся проблема в том, что рубиться очень много конектов в одну секунду, обычно, раз в час

Как можно решить эту проблему?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Broken Pipe в TCL, массовый обрыв коннектов"  
Сообщение от KeeperR email(ok) on 26-Апр-06, 20:03 
Еще забыл скзать,
если не убиваю сокет при ошибки Flush, то юзеры все равно вываливаются по EOF. То что у 70 процентов юзеров сразу EOF - плохо вериться....


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

2. "Broken Pipe в TCL, массовый обрыв коннектов"  
Сообщение от vt (ok) on 03-Май-06, 13:41 
>Еще забыл скзать,
>если не убиваю сокет при ошибки Flush, то юзеры все равно вываливаются
>по EOF. То что у 70 процентов юзеров сразу EOF -
>плохо вериться....

На первый взгляд - неплохо было бы проверять не блокирован ли socket
прежде чем в него записывать, а также добавить -buffering line в fconfigure,
раз уж чтение ведётся асинхронно, а запись - синхронно.
Второй взгляд сделать трудно )
Нужен либо полный текст, либо нормальный пример с сохранением функциональности,
но, действительно, без лишнего кода (sorry, но приведённый код - каша).
Можно также посмотреть подобные программы на wiki.tcl.tk

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

3. "Broken Pipe в TCL, массовый обрыв коннектов"  
Сообщение от KeeperR email(ok) on 07-Май-06, 20:07 
Я впринципе это зделал, проверял на блокировку сокет (зделал уже
поже). Но
проблема оставалась :).

1. Я тут разговаривал с одним человеком, он мне посоветовал использовать
потоки или разные интерпритоторы, но думаю, что это увеличит нагрузку
в разы. Потоки еще нужно указыать при компиляции. Это плохо.

При этом блокировать сокет.
Сейчас провер опыт. Я посылаю в сокет демона - символ x и жду 100
секнуд, после этого посылаю в сокет \n. В результате, демон не
принимает ни одного конекта в течение 100 сек, и вообще, как-бы виснит. Это как-то
лечиться?

2. И еще, если можно, помогите советом. Сейчас нагрузка на ЦП - 3-5%, при
80-100 человек в чате. В пиках до 50-70%. Я подумываю поставить
задержку.
after 100 например в одном цикле получения новых сообщений. Это может
привести к обрыву соединений? Тоесть, одим словом - это безопасно или
нет, или есть другие способы оптимизации?

3. Broken pipe, означет ли это невозможность востановления сокета, и
его обязательно нужно закрыть? Ведь сам по себе сокет не закрылся, а
proken pipe может быть .

Как посмотреть на то, что если я буду исполозовать заведомо большой
буфер, и я даже если сокет будет заблокирован , то я буду выполнять
puts но при этом , не выполнять flush. Как только сокет будет свободен
- произовадить flush. И если размер буфера достигнит критического -
рвать сокет по connection timeout.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Спонсоры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2022 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру