LINUX.ORG.RU

Падение сетевого сервера.


0

0

Есть сервак, который создает сокет:

int sock = socket(PF_INET, SOCK_STREAM, 0);
bind(sock, server_addr, sizeof(*server_addr));
listen(sock, 100);
int client = accept(sock, 0, 0);

далее он принимает от клиента один int и посылает клиенту два int

recv(client, &req, sizeof(req), 0);
send(client, &rep, sizeof(rep), 0);
send(client, &rep, sizeof(rep), 0);

Клиент подключается к серверу как:
int srv = socket(PF_INET, SOCK_STREAM, 0);
connect(srv, ......);

если теперь клиент выполнит такую последовательность:
recv(srv, &req, sizeof(req), 0);
send(srv, &rep, sizeof(rep), 0);
send(srv, &rep, sizeof(rep), 0);
close(srv);

то все будет ок, а если такую:
recv(client, &req, sizeof(req), 0);
close(srv);

то серверная часть вылетит на втором вызове send! Причем просто вылетит приложение перестает работать и возвращается в командную строку! Отмечу что сервер работает в отдельном потоке (pthread).

Собственно вопрос: Чего сделать чтобы сервак не вылетал?

anonymous

> Собственно вопрос: Чего сделать чтобы сервак не вылетал?

1. проверять коды возврата

2. читать Стивенса

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

В догонку:

1) Не передавай типы не фиксированного размера. sizeof(int) на клиенте и сервере могут различаться. Используй фиксированные типы: int32_t, uint64_t и т.п.

2) Учитывай порядок байт. Он так же может различаться. Обычно при передаче по сети используется "сетевой" порядок байт (big-endian), так что перед отправкой преобразуй число с помощью hton[s|l](), а после получения ntoh[s|l]().

Deleted
()

> Собственно вопрос: Чего сделать чтобы сервак не вылетал?

Поставить хэндлер на сигнал SIGPIPE. Или SIGPIPE поставить в SIG_IGN. man 2 signal.

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

Нет там кодов возврата! сбой происходит в системном вызове, программа в него входит но из него не выходит.

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

> Нет там кодов возврата! сбой происходит в системном вызове, программа в него входит но из него не выходит.

Попробуй signal(SIGPIPE, SIG_IGN); :)

mv ★★★★★
()

У Стивенса в деталях описываются практически все возможные 
ошибки при взаимодействии клиента и сервера.

У тебя классическая ошибка - читай про сигнал SIGPIPE.
Данный сигнал практически всегда необходимо игнорировать 
и проверять код возврата write на EPIPE.

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

> Не стал бы советовать человеку функцию signal

Глядишь, книжку прочитает, сам поймёт :)

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