Неправильная работа сетевых приложений при падении сети (Приложения не реагируют на падение сети)

Софт под Linux, разные программы, но только связанные с Linux

Модератор: /dev/random

Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Доброго времени, суток.

Обнаружил вот какую проблему.

Если я сейчас выну сетевой кабель из сетевой карты, то, хотя никакой сети уже не будет, все приложения, которые используют постоянное подключение, будут считать, что сеть работает. К примеру, jabber клиенты остаются подключенными к серверу, и когда я пытаюсь отослать кому-нибудь сообщение, никаких ошибок не возникает, и всё указывает на то, что сообщение отправлено, хотя, естественно, оно никак не может быть отправлено.

Если же вставить кабель обратно, то ничего не изменится - сеть работать все равно не будет, а приложения будут думать, что она работает.

Пробовал запускать /etc/init.d/networking restart и заново поднимать VPN соединение - сеть начинает работать, но те приложения, которые используют постоянное подключение, до сих пор не работают. А именно, они считают, что все нормально работает, а на самом не отсылают в сеть и байта информации. В случае jabber клиента это исправляется путем ухода в offline, а потом обратно в online (т. е. как раз этими действиями я закрываю постоянное TCP соединение и открываю новое).

В данном примере я сам выдергиваю сетевой кабель, но если неполадки в сети случились не по моей вине, то я никак не замечаю, что сеть не работает, и отправляю сообщения через jabber, которые не доходят до получателя, не подозревая об этом.

Данная проблема наблюдается как при работе в интернет по VPN соединению, так и в локальной сети.

Подскажите, пожалуйста, в какую сторону копать. Совершенно невозможно работать с IM клиентами - нет никакой гарантии, что сообщение дошло до получателя. :( Буду очень благодарен за помощь.



Информация, которая на мой взгляд может помочь в решении проблемы:
Ubuntu 7.04 (обновлялся с 6.10), eth0 - сеть между двумя компьютерами дома, через нее по NAT'у второй компьютер выходит в интернет, eth1 - локальная городская сеть, ppp0 - VPN подключение, соединяющее меня с интернетом.
Ниже приведен вывод команды ifconfig до вынимания сетевого кабеля и после.

До:

Код:

eth0 Link encap:Ethernet HWaddr 00:0F:EA:2E:E5:8F inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:19 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:3703 (3.6 KiB) Interrupt:19 Base address:0x4000 eth1 Link encap:Ethernet HWaddr 00:50:FC:F5:C6:DD inet addr:10.100.43.13 Bcast:10.100.43.255 Mask:255.255.255.0 inet6 addr: fe80::250:fcff:fef5:c6dd/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:39898 errors:0 dropped:0 overruns:0 frame:0 TX packets:62556 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3288355 (3.1 MiB) TX bytes:77257457 (73.6 MiB) Interrupt:21 Base address:0x4000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:20 errors:0 dropped:0 overruns:0 frame:0 TX packets:20 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1204 (1.1 KiB) TX bytes:1204 (1.1 KiB) ppp0 Link encap:Point-to-Point Protocol inet addr:192.168.85.222 P-t-P:172.16.16.1 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:9920 errors:0 dropped:0 overruns:0 frame:0 TX packets:14299 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:669641 (653.9 KiB) TX bytes:9848957 (9.3 MiB)

После:

Код:

eth0 Link encap:Ethernet HWaddr 00:0F:EA:2E:E5:8F UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:35 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:5660 (5.5 KiB) Interrupt:16 Base address:0xe000 eth1 Link encap:Ethernet HWaddr 00:50:FC:F5:C6:DD inet6 addr: fe80::250:fcff:fef5:c6dd/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4449 errors:0 dropped:0 overruns:0 frame:0 TX packets:5021 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:515277 (503.2 KiB) TX bytes:2812167 (2.6 MiB) Interrupt:21 Base address:0x6000 eth0:avah Link encap:Ethernet HWaddr 00:0F:EA:2E:E5:8F inet addr:169.254.8.205 Bcast:169.254.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:16 Base address:0xe000 eth1:avah Link encap:Ethernet HWaddr 00:50:FC:F5:C6:DD inet addr:169.254.12.145 Bcast:169.254.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:21 Base address:0x6000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:20 errors:0 dropped:0 overruns:0 frame:0 TX packets:20 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1204 (1.1 KiB) TX bytes:1204 (1.1 KiB)
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry, Вам нужно, чтобы сеть автоматически опускалась при отключении сетевого кабеля, или чтобы приложения при опускании сети автоматически это учитывали?
Если первое, то ifplugd.
Если второе, то это зависит от приложения, скажем, в Kopete есть специальный модуль для этого.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
07.07.2007 13:49
KonishchevDmitry, Вам нужно, чтобы сеть автоматически опускалась при отключении сетевого кабеля, или чтобы приложения при опускании сети автоматически это учитывали?
Если первое, то ifplugd.
Если второе, то это зависит от приложения, скажем, в Kopete есть специальный модуль для этого.
Мне бы хотелось, чтобы при отключении сетевого кабеля программы автоматически это распознавали, а при подключении сетевого кабеля сеть автоматически поднималась. Насчет модулей - если взять к примеру Psi, то под Windows он при отключении сетевого кабеля распознает, что соединения с сервером нет, а вот в Linux он этого не делает. Так как Psi - не модульный клиент, то на мой скромный взгляд проблема в самой системе.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
07.07.2007 15:50
при подключении сетевого кабеля сеть автоматически поднималась.

Это как раз к ifplugd.
KonishchevDmitry писал(а):
07.07.2007 15:50
под Windows он при отключении сетевого кабеля распознает, что соединения с сервером нет, а вот в Linux он этого не делает. Так как Psi - не модульный клиент, то на мой скромный взгляд проблема в самой системе.

На мой скромный взгляд проблема в Psi, в котором в Windows-реализацию включили эту возможность, а Linux - нет.
Ну подумайте: система, обнаружив, что сетевой кабель не подключён (по косвенным признакам), опускает сеть. Она что, должна ещё и каждое приложение в оффлайн перевести? А откуда она узнает, как переводить в оффлайн мою недавно написанную на коленке программу? Так что проблема, очевидно, совсем не в системе, ибо Kopete и KGet прекрасно обнаруживают, что соединения нет, и отправляются в автономный режим или "вне сети".
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Поставил себе Kopete, подключил в нем модуль Connection Status и начал экспериментировать. Вот что я заметил:
Если просто выдернуть сетевой кабель, то Kopete не замечает, что сети нет (ждал 10 минут).
Если после выдергивания сетевого кабеля вручную опустить интерфейс (ifconfig eth1 down), то через 30 секунд Kopete определяет, что сети нет и отключается от сервера.
После установки ifplugd интерфейсы начали сами подниматься, но все равно Kopete не обнаруживает отключение от сети.

Rootlexx писал(а):
07.07.2007 16:31
Ну подумайте: система, обнаружив, что сетевой кабель не подключён (по косвенным признакам), опускает сеть. Она что, должна ещё и каждое приложение в оффлайн перевести? А откуда она узнает, как переводить в оффлайн мою недавно написанную на коленке программу? Так что проблема, очевидно, совсем не в системе, ибо Kopete и KGet прекрасно обнаруживают, что соединения нет, и отправляются в автономный режим или "вне сети".
Честно говоря, мое понимание в этой области очень расплывчатое, поэтому предупреждаю, что могу сказать глупость. :) Лично я себе это представляю как:
1) Не правильно работает реализация Keep Alive в TCP, т. к., насколько я знаю, протокол TCP обеспечивает надежную доставку данных при включенном режиме Keep Alive, и если пакеты не дошли до получателя, то функция recv возвращает код ошибки.
2) Лично мне бы показалось логичным, если бы система сама закрывала все "сломанные" сокеты приложения, а приложению бы требовалось только переодически проверять сокет на валидность.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
07.07.2007 20:06
После установки ifplugd интерфейсы начали сами подниматься, но все равно Kopete не обнаруживает отключение от сети.

А Вы настраивали ifplugd? Чтобы он сам опускал интерфейсы? Тогда и Kopete обнаружит потерю сети.
KonishchevDmitry писал(а):
07.07.2007 20:06
1) Не правильно работает реализация Keep Alive в TCP, т. к., насколько я знаю, протокол TCP обеспечивает надежную доставку данных при включенном режиме Keep Alive, и если пакеты не дошли до получателя, то функция recv возвращает код ошибки.
2) Лично мне бы показалось логичным, если бы система сама закрывала все "сломанные" сокеты приложения, а приложению бы требовалось только переодически проверять сокет на валидность.

При обрыве соединения и попытке послать что-нибудь, если сокет типа SOCK_STREAM, процессу посылается SIGPIPE. В дополнение к этому функция send вернёт ошибку, так что тут уже дело приложения, что именно делать. А система ничего не должна делать во время исполнения приложения, только после его завершения она может закрыть дескрипторы, почистить память. Да и закрытие дескриптора сокета будет означать, что придётся создавать его заново вместо вызова connect, если он вдруг снова понадобится.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
07.07.2007 21:00
А Вы настраивали ifplugd? Чтобы он сам опускал интерфейсы? Тогда и Kopete обнаружит потерю сети.
Судя по логу, он опускает нужный мне интерфейс eth1 (Kopete тестировался на локальном jabber сервере).

Код:

ifplugd 0.28 initializing. Using interface eth1/00:50:FC:F5:C6:DD with driver <8139too> (version: 0.9.28) Using detection mode: SIOCETHTOOL Initialization complete, link beat detected. Executing '/etc/ifplugd/ifplugd.action eth1 up'. client: /sbin/ifup: interface eth1 already configured Program executed successfully. Link beat lost. Executing '/etc/ifplugd/ifplugd.action eth1 down'. client: RTNETLINK answers: No such process client: postconf: fatal: open /etc/postfix/main.cf: No such file or directory client: There is already a pid file /var/run/dhclient.eth1.pid with pid 134993416 client: Internet Systems Consortium DHCP Client V3.0.4 client: Copyright 2004-2006 Internet Systems Consortium. client: All rights reserved. client: For info, please visit http://www.isc.org/sw/dhcp/ client: Listening on LPF/eth1/00:50:fc:f5:c6:dd client: Sending on LPF/eth1/00:50:fc:f5:c6:dd client: Sending on Socket/fallback client: DHCPRELEASE on eth1 to 10.100.64.19 port 67 Program executed successfully. Link beat detected. Executing '/etc/ifplugd/ifplugd.action eth1 up'. client: There is already a pid file /var/run/dhclient.eth1.pid with pid 7342 client: killed old client process, removed PID file client: Internet Systems Consortium DHCP Client V3.0.4 client: Copyright 2004-2006 Internet Systems Consortium. client: All rights reserved. client: For info, please visit http://www.isc.org/sw/dhcp/ client: Listening on LPF/eth1/00:50:fc:f5:c6:dd client: Sending on LPF/eth1/00:50:fc:f5:c6:dd client: Sending on Socket/fallback client: DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 3 client: DHCPOFFER from 10.100.43.1 client: DHCPREQUEST on eth1 to 255.255.255.255 port 67 client: DHCPACK from 10.100.43.1 client: bound to 10.100.43.13 -- renewal in 1535 seconds. client: RTNETLINK answers: File exists client: run-parts: /etc/network/if-up.d/avahi-autoipd exited with return code 2 client: postconf: fatal: open /etc/postfix/main.cf: No such file or directory Program executed successfully.

Rootlexx писал(а):
07.07.2007 21:00
При обрыве соединения и попытке послать что-нибудь, если сокет типа SOCK_STREAM, процессу посылается SIGPIPE. В дополнение к этому функция send вернёт ошибку, так что тут уже дело приложения, что именно делать. А система ничего не должна делать во время исполнения приложения, только после его завершения она может закрыть дескрипторы, почистить память. Да и закрытие дескриптора сокета будет означать, что придётся создавать его заново вместо вызова connect, если он вдруг снова понадобится.
Ради интереса решил проверить у себя. Написал программу, которая начинает прослушивать порт, сама же соединяется с этим портом, ждет 10 секунд и отправляет данные на этот порт. В течение этих 10 секунд я пускал интерфейс.

Результаты получились довольно странные:
1) Опустил все интерфейсы, оставил только lo и eth0 (192.168.0.1). Запускаю программу, в течение тех 10 секунд выполняю ifconfig eth0 down. Программа выводит:

Код:

send return 4 Sent data: 1234 Client accepted recv return 4 Received data: 1234
т. е. хотя, интерфейс опущен, данные каким-то чудесным образом дошли. :wacko:

2) Опустил все интерфейсы, оставил только lo и eth0 (192.168.0.1). Запускаю программу, в течение тех 10 секунд выполняю ifconfig eth0 down; ifconfig eth0 192.168.0.2 up (меняю IP адрес на другой). Программа выводит:

Код:

send return 4 Sent data: 1234 Client accepted
и вечно ждет, когда придут данные от клиента.

В обоих случаях функция send не вернула ошибки.
Вот листинг тестовой программы:

Код:

void connect2server(char *server_ip, int server_port) { int server_socket; int data = 1234; struct sockaddr_in server_socket_properties; if( (server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) return; server_socket_properties.sin_family = AF_INET; server_socket_properties.sin_port = htons(server_port); inet_aton(server_ip, &server_socket_properties.sin_addr); if(connect(server_socket, (struct sockaddr *) &server_socket_properties, sizeof(server_socket_properties)) == -1) return; sleep(10); printf("send return %d\n", send(server_socket, &data, 4, MSG_NOSIGNAL)); printf("Sent data: %d\n", data); } int main() { int i; struct sockaddr_in server_socket_properties, client_socket_properties; int server_socket, client_socket; int client_addrlen; int buf; if( (server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) puts("Unable to create socket"); server_socket_properties.sin_family = AF_INET; server_socket_properties.sin_port = htons(12345); inet_aton("192.168.0.1", &server_socket_properties.sin_addr); if(bind(server_socket, (struct sockaddr *) &server_socket_properties, sizeof(server_socket_properties)) == -1) puts("Unable to bind port"); if(listen(server_socket, 2) == -1) puts("Unable to listen"); client_addrlen = sizeof(client_socket_properties); connect2server("192.168.0.1", 12345); if( (client_socket = accept(server_socket, (struct sockaddr *) &client_socket_properties, (socklen_t *) &client_addrlen)) == -1) puts("Unable to accept"); puts("Client accepted"); printf("recv return %d\n", recv(client_socket, &buf, 4, 0)); printf("Received data: %d\n", buf); if(close(server_socket)) puts("Can not close server socket."); return 0; }
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
08.07.2007 10:41
и вечно ждет, когда придут данные от клиента.

Вы не пометили сокет, как неблокирующий:

Код: Выделить всё

#include <unistd.h>
#include <fcntl.h>
...
fcntl(socket, F_SETFL, O_NONBLOCK);

, поэтому recv ждёт прибытия данных, а не возвращает ошибку.
То, что функция send в обоих случаях не вернула ошибку, естественно, ибо данные были посланы, а -1 возвращается только в случае локальной ошибки (из man 2 send):
No indication of failure to deliver is implicit in a send(). Locally detected errors are indicated by a return value of -1.

KonishchevDmitry писал(а):
08.07.2007 10:41
inet_aton("192.168.0.1", &server_socket_properties.sin_addr);

Код: Выделить всё

server_socket_properties.sin_addr.s_addr=inet_addr("192.168.0.1");

Покажите вывод ifconfig после опускания интерфейса eth0.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
08.07.2007 15:40
Вы не пометили сокет, как неблокирующий, поэтому recv ждёт прибытия данных, а не возвращает ошибку.
Но даже если пометить сокет как неблокирующий, то все равно ошибку по возвращаемому значению определить не удастся. Если брать случай когда я опускаю сокет и дополнительно меняю для него IP адрес, то recv возвращает -1, errno выставляется в 11, а perror выводит "Resource temporarily unavailable". То же самое будет происходить, если клиент просто не будет ничего отсылать серверу.

Rootlexx писал(а):
08.07.2007 15:40
То, что функция send в обоих случаях не вернула ошибку, естественно, ибо данные были посланы, а -1 возвращается только в случае локальной ошибки (из man 2 send):
No indication of failure to deliver is implicit in a send(). Locally detected errors are indicated by a return value of -1.
Да, это я читал, но тогда я что-то слабо понимаю, что значит локальная ошибка. Я опустил сокет, ни о какой передаче данных с моей машины теперь не может быть и речи - куда уж локальней? :)

Rootlexx писал(а):
08.07.2007 15:40
Покажите вывод ifconfig после опускания интерфейса eth0.

Код:

# ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:399 errors:0 dropped:0 overruns:0 frame:0 TX packets:399 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:24112 (23.5 KiB) TX bytes:24112 (23.5 KiB)


P.S.: Спасибо Вам огромное, что не жалеете свое время на решение моих проблем. Очень Вам благодарен. :blush:
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
08.07.2007 16:23
То же самое будет происходить, если клиент просто не будет ничего отсылать серверу.

Но ведь можно сделать так:

Код: Выделить всё

#include <signal.h>

int my_funct()
{
       fprintf(stderr, "An error occured!\n");
       return 1;
}
...
       signal(SIGPIPE, (void *)my_funct);
...

При разрыве соединения процессу будет послан сигнал SIGPIPE (только не надо посылать с MSG_NOSIGNAL), в результате чего управление будет передано на handler функции, указанной в signal, в данном случае - int my_funct(). Там и обрабатывать (отключаться от сети, выводить сообщение об ошибке и тому подобное).
KonishchevDmitry писал(а):
08.07.2007 16:23
Но даже если пометить сокет как неблокирующий, то все равно ошибку по возвращаемому значению определить не удастся. Если брать случай когда я опускаю сокет и дополнительно меняю для него IP адрес, то recv возвращает -1, errno выставляется в 11, а perror выводит "Resource temporarily unavailable".

По крайней мере виснуть программа не будет (можно ещё timeout установить).
При разрыве соединения errno устанавливается в EPIPE.
А вот с пересылкой данных по опущенному интерфейсу буду разбираться :wacko: .
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
08.07.2007 18:02
Но ведь можно сделать так:

Код: Выделить всё

#include <signal.h>

int my_funct()
{
       fprintf(stderr, "An error occured!\n");
       return 1;
}
...
       signal(SIGPIPE, (void *)my_funct());
...

Странно, у меня my_funct() запускается сразу же после установки на нее сигнала. А если еще эту функцию изменить так:

Код:

int my_funct() { fprintf(stderr, "An error occured!\n"); signal(SIGPIPE, (void *)my_funct()); return 1; }
, то получаю на терминале бесконечное "An error occured!". Т. е. получается, что сигнал SIGPIPE у меня генерируется постоянно.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
08.07.2007 19:02
Странно, у меня my_funct() запускается сразу же после установки на нее сигнала. А если еще эту функцию изменить так:
CODE
int my_funct()
{
fprintf(stderr, "An error occured!\n");
signal(SIGPIPE, (void *)my_funct());
return 1;
}
, то получаю на терминале бесконечное "An error occured!". Т. е. получается, что сигнал SIGPIPE у меня генерируется постоянно

Нет, в вызове signal должен присутствовать handler функции, а не вызов, то есть:

Код: Выделить всё

signal(SIGPIPE, (void *)my_funct);

У Вас это передача обработки сигнала SIGPIPE на handler, возвращённый функцией int my_funct(), а не handler на саму эту функцию.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
08.07.2007 20:00
У Вас это передача обработки сигнала SIGPIPE на handler, возвращённый функцией int my_funct(), а не handler на саму эту функцию.
ОЙ, прошу прощения. :blush: Случайно захватил скобки при копировании имени функции. Но в таком случае у меня при опускании интерфейсов вообще не возникает сигнала SIGPIPE.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry писал(а):
08.07.2007 20:28
при опускании интерфейсов вообще не возникает сигнала SIGPIPE

Этот сигнал возникает, когда Вы пытаетесь что-то передать через сокет, но соединение оборвано.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
08.07.2007 20:47
Этот сигнал возникает, когда Вы пытаетесь что-то передать через сокет, но соединение оборвано.
Ну да. У меня ведь в программе стоит sleep(10), а за ним send. Пока работает sleep, я опускаю интерфейс. Или Вы хотите сказать, что опускание интерфейса не является разрывом соединения?
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4471
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Неправильная работа сетевых приложений при падении сети

Сообщение Rootlexx »

KonishchevDmitry, приведите код модифицированной программы, пожалуйста.
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Неправильная работа сетевых приложений при падении сети

Сообщение KonishchevDmitry »

Rootlexx писал(а):
08.07.2007 21:59
KonishchevDmitry, приведите код модифицированной программы, пожалуйста.

Код:

#include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <errno.h> #include <signal.h> int my_funct() { fprintf(stderr, "An error occured!\n"); return 1; } void connect2server(char *server_ip, int server_port) { int server_socket; int data = 1234; struct sockaddr_in server_socket_properties; if( (server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) return; server_socket_properties.sin_family = AF_INET; server_socket_properties.sin_port = htons(server_port); inet_aton(server_ip, &server_socket_properties.sin_addr); if(connect(server_socket, (struct sockaddr *) &server_socket_properties, sizeof(server_socket_properties)) == -1) return; sleep(10); printf("send return %d\n", send(server_socket, &data, 4, 0)); printf("Sent data: %d\n", data); } int main() { int i; struct sockaddr_in server_socket_properties, client_socket_properties; int server_socket, client_socket; int client_addrlen; int buf; signal(SIGPIPE, (void *)my_funct); if( (server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) puts("Unable to create socket"); server_socket_properties.sin_family = AF_INET; server_socket_properties.sin_port = htons(23469); inet_aton("192.168.0.1", &server_socket_properties.sin_addr); if(bind(server_socket, (struct sockaddr *) &server_socket_properties, sizeof(server_socket_properties)) == -1) puts("Unable to bind port"); if(listen(server_socket, 2) == -1) puts("Unable to listen"); client_addrlen = sizeof(client_socket_properties); connect2server("192.168.0.1", 23469); if( (client_socket = accept(server_socket, (struct sockaddr *) &client_socket_properties, (socklen_t *) &client_addrlen)) == -1) puts("Unable to accept"); puts("Client accepted"); printf("fcntl return %d\n", fcntl(client_socket, F_SETFL, O_NONBLOCK)); printf("recv return %d\n", recv(client_socket, &buf, 4, 0)); printf("errno: %d\n", errno); perror(""); printf("Received data: %d\n", buf); if(close(server_socket)) puts("Can not close server socket."); return 0; }

Вывод при нормальной работе:

Код:

send return 4 Sent data: 1234 Client accepted fcntl return 0 recv return 4 errno: 0 Success Received data: 1234

Вывод при нормальной работе и закоментированной строке "printf("send return %d\n", send(server_socket, &data, 4, 0));"

Код:

Sent data: 1234 Client accepted fcntl return 0 recv return -1 errno: 11 Resource temporarily unavailable Received data: 134514448

Вывод при отключении интерфейса и смене IP адреса:

Код:

send return 4 Sent data: 1234 Client accepted fcntl return 0 recv return -1 errno: 11 Resource temporarily unavailable Received data: 134514496
Спасибо сказали: