LINUX.ORG.RU

Клиент отваливается - сервер падает


0

0

Написал клиент-серверное приложение по стивенсу. На сервере на каждый коннект создается поток. При установке соединения сервер начинает отправлять клиенту данные. Если на клиенте сделать кенцел, сервер падает. Как отловить на сервере аварийное отключение клиента ?

Чтобы не быть голословным :
    Pthread_create(&tid, NULL, &doit, iptr);

Функция doit:

doit(void *arg)
{
	int		connfd;

	connfd = *((int *) arg);
	free(arg);

	Pthread_detach(pthread_self());
	str_echo(connfd);		/* same function as before */
	Close(connfd);			/* we are done with connected socket */
	return(NULL);
}


Функция str_echo :
void str_echo(int sockfd)
{
    ssize_t     n;
    char        line[MAXLINE];
    n=0;
    int count=5;

    for ( ; ; ) 
    {
        sprintf(line,"%d\n",n);
        Writen(sockfd, line, strlen(line));
        n +=1;
    }
}

Сервер валится где-то в районе Written , поскольку дескриптор сокета уже накрылся ...

iivvaann
() автор топика

SIGPIPE?

Попробуй добавить в начало:

        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = SIG_IGN;
        if (-1 == sigaction(SIGPIPE, &sa, NULL))
        {
                /* ERROR: Can't ignore SIGPIPE. */
        }

Если поможет, значит твоя программа умирает от сигнала SIGPIPE, который ядро посылает при попытке записи в поток, который уже закрыт с другой стороны. Этот код позволяет программе игнорировать этот сигнал.

Deleted
()
Ответ на: комментарий от Boy_from_Jungle

>> sprintf(line,"%d\n",n);
> Что-то не так здесь?! Не кажеться?!


Падает не из-за этого. Хотя тут ошибка, да =).

Deleted
()
Ответ на: комментарий от mv

>> signal(SIGPIPE, sig_pipe_handler);

О - работает ! Только цикл Written теперь повис :-)

iivvaann
() автор топика
Ответ на: SIGPIPE? от Deleted

> Этот код позволяет программе игнорировать этот сигнал.

Только не забывай проверять значение, которые возвращают вызовы write и других функций.

Deleted
()
Ответ на: комментарий от Deleted

Все работает. Только один момент неясен : после того , как клиент отвалился , сервер ловит исключение и продолжает работать . Но топ показывает , что сервер стал грузить цпу на 100 % ...

iivvaann
() автор топика
Ответ на: комментарий от iivvaann

>сервер ловит исключение

Какое исключение, это Си. И не ловите и не обрабатываете, а просто игнорируете ошибку записи в сокет. Вот и получаете бесконечно быстрый цикл.

mky ★★★★★
()
Ответ на: комментарий от mv

> signal(SIGPIPE, sig_pipe_handler);

Можно даже заигнорить его нафиг: write по-любому EPIPE выставит.

const86 ★★★★★
()
Ответ на: комментарий от iivvaann

>    for ( ; ; ) 
            ^ хде выход по закрытию сокета со стороны клиента? O_o

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.