Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/18: Рейтинг темы: голосов - 18, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13

Программа падает на функции send()

08.06.2013, 10:32. Показов 3621. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Пишу webproxy.

Вроде все работает:
Посылаю запрос на proxy, proxy парсит заголовки, создает соединение к удаленному серверу и запрашивает страницу, получает страницу, обрабатывает и отдает ее клиенту.

Возникла проблема, если я резко в браузере обновляю страницу (не дожидаюсь загурзки) то программа вылетает на функции send (write) sockets функции WriteData

Вылетает при пересылки данных от proxy к клиенту. Возможность записи в сокет клиента проверяю (w1)

Пробую как в cygwin так и на unix сервере



C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int WriteData( int fd, char *data, int len, int *wr_len, int dbg )
{
    int ret;
    int wr_buf_size;
    if( len > *wr_len)
    {
        wr_buf_size = (((len-*wr_len) > rcvbuf_size) ? rcvbuf_size : (len-*wr_len));
        memmove( rcvbuf_pntr, (data+*wr_len), wr_buf_size);
        ret = send( fd, rcvbuf_pntr, wr_buf_size, 0 ); ////////////////////////// Строка после которой прокси падает
        if(ret > 0)
        {
            *wr_len += ret;
            *(rcvbuf_pntr + ret) = '\0';
            (void) debug( dbg, "%s", rcvbuf_pntr );
        }
        return(ret);
    }
    return(0);
}
Фрагмент proxy:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    if ( (servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        debug( DEBUG_FATAL, "Error create socket. Function <socket> return [%d]. Errno [%d]\r\n", servfd, errno );
    }
 
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons( port);
    
    if ( (ret=bind( servfd, (struct sockaddr*) &servaddr, sizeof(servaddr))) < 0) {
        close( servfd);
        debug( DEBUG_FATAL, "Error exec bind. Function <bind> return [%d]. Errno [%d]\r\n",  ret,  errno );
    }
    
    if( (ret=listen( servfd, 32)) < 0 ) {
        close( servfd);
        debug( DEBUG_FATAL, "Error exec listen. Function <listen> return [%d]. Errno [%d]\r\n",  ret,  errno );
    }
...

C
1
2
    FD_ZERO(&allfds);
    FD_SET(servfd, &allfds);
...

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
        readfds = writefds =  allfds;
        nready = select( (maxfd+1), &readfds, &writefds, NULL, NULL);
        /****************************************************************
        * 
        ****************************************************************/
        if(  cur_client < 16 && FD_ISSET(servfd, &readfds)) 
        {
            clilen = sizeof(cliaddr);
            allclients +=1;
            cur_client++;
DEBUG_LINE              clientfd = accept(servfd, (struct sockaddr*) &cliaddr, &clilen);
            
            debug( DEBUG_MSG, ">>>New client. Fd connection [%d, %d, %d]\r\n",cur_client,  clientfd, allclients );
            
            for(i = 0; i < FD_SETSIZE; i++)
            {
                if( clients[i].clientfd < 0) /* Сохраняем клиента в свободной ячейки */
                {
                    clients[i].clientfd = clientfd;
                    clients[i].step = pINIT;
                    time( &clients[i].starttime );
                    break;
                }
            }
            
            if(i == FD_SETSIZE)
            {
                debug( DEBUG_FATAL, "too many clients");
                exit(0);
            }
 
            FD_SET(clientfd, &allfds);  /* add new descriptor to set */
            if(clientfd > maxfd) maxfd = clientfd;  /* for select */
        }
 
...
        for(i = 0; i < FD_SETSIZE; i++)
        {
            if( (sockfd = clients[i].clientfd) < 0) continue;
            
            clients[i].r1 = (( FD_ISSET(clients[i].clientfd, &readfds) ) ? 1 : 0);
            clients[i].w1 = (( FD_ISSET(clients[i].clientfd, &writefds) ) ? 1 : 0);
            clients[i].r2 = (( clients[i].reqfd > 0 && FD_ISSET(clients[i].reqfd, &readfds) ) ? 1 : 0);
            clients[i].w2 = (( clients[i].reqfd > 0 && FD_ISSET(clients[i].reqfd, &writefds) ) ? 1 : 0);
        }
 
...
Создаем удаленное подключение:
 
        {
DEBUG_LINE      debug( DEBUG_MSG,  "Create request host [%s]\r\n", clients[m].host );
 
            struct sockaddr_in   reqaddr;
            struct hostent      *hptr;
            char **pptr;
            char addr[46];
            int fd;
            
            bzero( &reqaddr, sizeof( reqaddr));
            bzero( &hptr, sizeof( hptr));
            
            if ( (hptr = gethostbyname( clients[m].host )) == NULL )
            {
                switch (errno) 
                {
                    case HOST_NOT_FOUND:    debug( DEBUG_MSG, "GetHostByName(%s) Err TRY_AGAIN\r\n",    clients[m].host); break;
                    case TRY_AGAIN:         debug( DEBUG_MSG, "GetHostByName(%s) Err NO_RECOVERY\r\n",  clients[m].host); break;
                    case NO_RECOVERY:       debug( DEBUG_MSG, "GetHostByName(%s) Err NO_DATA\r\n",      clients[m].host); break;
                    case NO_DATA:           debug( DEBUG_MSG, "GetHostByName(%s) Err NO_NAME\r\n",      clients[m].host); break;
                    default:            debug( DEBUG_MSG, "GetHostByName(%s) Err ???\r\n",      clients[m].host);   break;
                }
                clients[m].step = e503_SERVICE_UNAVAILABLE;
                break;
            }
            
            inet_ntop(hptr->h_addrtype, (char*)*hptr->h_addr_list, addr, sizeof(addr));
            
            reqaddr.sin_addr.s_addr = inet_addr( addr);
            reqaddr.sin_family = AF_INET;
            reqaddr.sin_port = htons( clients[m].port);
 
            debug( DEBUG_MSG, "Request addr [%s] port [%d]\r\n", addr, clients[m].port);
 
DEBUG_LINE              if ( (fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 
            {
                close( fd );
                debug( DEBUG_WARNING, "Warning create socket. Function <socket> return [%d]. Errno [%d]\r\n", clients[m].reqfd, errno );
                clients[m].step = e503_SERVICE_UNAVAILABLE;
                break;
            }
DEBUG_LINE              
            if( (ret=connect( fd, (struct sockaddr*) &reqaddr, sizeof(reqaddr))) < 0 )
            {
                close( fd );
                debug( DEBUG_ERROR, "Error exec connect. Function <connect> return [%d]. Errno [%d]\r\n", ret, errno );
                clients[m].step = e503_SERVICE_UNAVAILABLE;
                break;
            }
DEBUG_LINE              
            clients[m].reqfd = fd;
            FD_SET( fd, &allfds);
            if(fd > maxfd)
            {
                maxfd = fd;         /* for select */
            }
 
            clients[m].step = pCGI2SERV_HEAD_MAKE;
...

Удаляем клиента:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mCLIENT_UNSET:;
 
DEBUG_LINE      debug( DEBUG_MSG, "GOODBAY %i\r\n", clients[m].clientfd );
 
            shutdown( clients[m].clientfd, 2 );
            close( clients[m].clientfd );
            FD_CLR( clients[m].clientfd, &allfds);
            clients[m].clientfd = -1;
            
            if( clients[m].reqfd > 0)
            {
                close( clients[m].reqfd );
                FD_CLR( clients[m].reqfd, &allfds);
                clients[m].reqfd =-1;
            }
            
            cur_client--;
...

Вылетает в этом блоке на функции WriteData:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DEBUG_LINE      if( clients[m].w1 == 0) break;
DEBUG_LINE              
            if( clients[m].bufh_len > clients[m].cur_wr_size)
            {
DEBUG_LINE          ret = WriteData( clients[m].clientfd, clients[m].bufh, clients[m].bufh_len, &clients[m].cur_wr_size, 0 ); 
DEBUG_LINE          if( ret < 0)
                {
DEBUG_LINE              debug( DEBUG_ERROR, "Error write body request. Function <write> return [%d]. Errno [%d]\r\n", ret, errno );
                    clients[m].step = e503_SERVICE_UNAVAILABLE;
                    break;
                }
                else if( ret > 0 && clients[m].bufh_len > clients[m].cur_wr_size)
                {
DEBUG_LINE              (void) debug( DEBUG_MSG, "\r\n[fd%02i] [%02i] +%04i %06i - %06i ", clientfd, step, ret, (clients[m].cur_wr_size-ret), clients[m].cur_wr_size );
                    clients[m].step = pCGI2CLI_WR_HTML_HEAD2;
                    break;
                }
                
                (void) debug( DEBUG_MSG, "\r\n[fd%02i] [%02i] +%04i %06i - %06i ", clientfd, step, ret, (clients[m].cur_wr_size-ret), clients[m].cur_wr_size );
            }
            
            (void) debug( DEBUG_MSG, "\r\n[fd%02i] [%02i] ... OK \r\n", clientfd, step );

Подскажите, пожалуйста, в чем может быть проблема.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.06.2013, 10:32
Ответы с готовыми решениями:

Ошибка в функции send() как исправить
Есть 2 программы: клиент и сервер, клиент должен посылать серверу сообщение &quot;hello&quot; а программа сервера должна это сооющение выводить...

Сокеты: после вызова send программа зависает на функции recv
Извеняюсь за такое назание темы, но уже перепробовал 100 вариантов и постоянно выкидывает данное предупреждение, уже и не знаю что блин...

Почему при ответе на пакет ( recv / send ) скорость очень сильно падает ?
Добрый день. Объясните, пожалуйста, в чем дело ? Драйвер на основе примера mux из WinDDK передает, и принимает пакеты на большой...

12
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.06.2013, 16:31
Что значит падает?
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
08.06.2013, 16:57  [ТС]
Падает... Ну как бы прокси должен постоянно висеть в памяти и слушать порт а при таком обращении (Refresh) выходит из программы с ожиданием новой команды в консоли.

---
Вспомнилось:
Читаю данные с удаленного сервера, метод передачи Transfer-Encoding: chunked, заголовки которые отправляю от proxy к клиенту не меняю (сейчас данный заголовок удаляю и отправляю Content-Length) но тело отправляю html текстом без разделителей r\n[hex_size]\r\n и так же вылетает на функции write (send) такое ощущение что клиент (веб браузер) не увидел размер части тела и просто закрывает соединение и из за этого и падает программа. Сокет выбираю на готовность чтения и записи и тогда уже продолжаю обрабатывать в программе данные, т.е. вроде все правильно делаю.

На возможные exit(0); в программе ставил отладочную информацию, ничего не выяснил
Вложения
Тип файла: zip proxy.zip (11.1 Кб, 12 просмотров)
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.06.2013, 17:03
Еще раз, это сигфолт? -1 в send() ? что-то другое?
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
08.06.2013, 17:09  [ТС]
Если я вас правильно понял (-1 это возвращаемое значение функции send, означающее ошибку) то никакой ошибки не возвращается, программа просто падает. Делаю так (отладочная информация):

printf("%i\r\n", __LINE__);
ret = send( fd, rcvbuf_pntr, wr_buf_size, 0 );
printf("%i\r\n", __LINE__);

В итоге не видим номер строки после функции send()


А можно на англиском языке значение сигфолт, почитаю что это такое
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.06.2013, 17:20
segfolt оно же Segmentation fault
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
08.06.2013, 17:24  [ТС]
всё сообразил, были такие сообщения иногда.
В данном случае не было такого сообщения, просто завершение программы и запрос новой команды в консоле $
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.06.2013, 17:33
6oTaHuK, ну запустите под отладчиком. Там скажут за что убили. Или в системном логе посмотрите. Правда, причину кроме проблем с rcvbuf_pntr придумать сложно.
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
08.06.2013, 17:55  [ТС]
Посмотрите пожалуйста архив в 3-ем сообщении кто разбирается в сокетах, может что не так, может необходимо что то дополнительно проверить кроме вызовом функции select перед вызовом функции send

Добавлено через 2 минуты
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
6oTaHuK, ну запустите под отладчиком. Там скажут за что убили. Или в системном логе посмотрите. Правда, причину кроме проблем с rcvbuf_pntr придумать сложно.
Попробую поиграть с отправляемыми данными... Сейчас попробую и напишу результат

Добавлено через 18 минут
Попробовал, изменил функцию:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int WriteData2( int fd, char *data, int len, int *wr_len, int dbg )
{
    int i, ret;
    int wr_buf_size;
    
    char text[]="gggggggggggggggg gggggggggggggggggggg";
    
    if( len > *wr_len)
    {
        wr_buf_size = (((len-*wr_len) > rcvbuf_size) ? rcvbuf_size : (len-*wr_len));
        memmove( rcvbuf_pntr, (data+*wr_len), wr_buf_size);
    printf("%i\r\n", __LINE__);
        ret = send( fd, &text[0], strlen(text), 0 );
    printf("%i\r\n", __LINE__);
        if(ret > 0)
        {
            *wr_len += ret;
            *(rcvbuf_pntr + ret) = '\0';
            (void) debug( dbg, "%s", rcvbuf_pntr );
        }
        return(ret);
    }
    return(0);
Результат:

Так же вызов функции send произошел но на ней же и прервалась программа т.е. номер строки за функцией send не вывел в окно терминала

---
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.06.2013, 18:05
Ищите, где портите rcvbuf_pntr и возможно все, что объявлено за ним.
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
09.06.2013, 05:39  [ТС]
Ну слово "портить" новое для меня... Это первая программа на СИ...
А то что прямо в функции объявил строку char text[]="gggggggggggggggg gggggggggggggggggggg"; и ее же передаю мне кажется с rcvbuf_pntr снимает подозрения.

Только что проверил прокси написанный н php и работающий на этом же сетевом диске, вроде таких прблем не возникло (refresh, F5)

Добавлено через 11 часов 24 минуты
Уважаемая администрация, удалите пожалуйста вложение в третьем сообщении

Урл
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
09.06.2013, 08:03  [ТС]
Выложу исходники, буду благодарен если кто глянет

Достучаться до прокси можно по адресу:
localhost:8080/webproxy/03/http/www.yandex.ru/
Вложения
Тип файла: zip proxy.zip (18.9 Кб, 5 просмотров)
0
0 / 0 / 0
Регистрация: 08.06.2013
Сообщений: 13
10.06.2013, 03:39  [ТС]
Запустил с дебагером, вот результат:

Code
1
2
3
4
5
6
7
8
Program received signal SIGPIPE, Broken pipe.
0x00000000 in ?? ()
(gdb) Q
A debugging session is active.
 
        Inferior 1 [process 3804] will be killed.
 
Quit anyway? (y or n) Y
Буду копать в этом направлении (SIGPIPE)

---
Добавил (может не корректно, позже буду разбираться):

signal(SIGPIPE, SIG_IGN);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.06.2013, 03:39
Помогаю со студенческими работами здесь

Почему программа "падает" на функции заполнения дерева?
Здравствуйте! У меня проблема с заполнением дерева. #include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; ...

Нужен урок по функции Send Keys
Пробовал SendKeys.Sand все замечательно, но эта функция позволяет только сэмитировать нажатие и отжатие клавиши сразу, но не дает выбрать...

Функции puts(), send(), recv() и какая-то дичь
Всем здравствовать! Столкнулся с невероятно непонятной мне вещью и просто уже не могу... не могу разобраться. Написал я значится...

Программа падает
/**************************************************************************** * ...

Падает программа
Здравствуйте. Нужно написать программу, которая последовательно отображает два экрана. На первом надпись &quot;Добро пожаловать&quot; и...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru