Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048

Простейший proxy на уровне IP

17.02.2013, 21:25. Показов 961. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Понадобилось мне накидать простейший proxy на уровне IP, чтобы перекидывать
соединение на конкретный порт FreeBSD 9.0 STABLE с реальным IP-номером на
конкретный порт другой машины в локальной сети с локальным IP-номером.
Я и накатал. Код прокси-сервера тут :
Code
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
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
 
int main()
{
    int         r, s, sd, cd, pd ;
    struct sockaddr_in  sa, ca, pa ;
    char            buf[0x1000] ;
 
    if (r = fork())
    {
        if (r == -1)
        {
            perror(NULL) ;
            return 1 ;
        }
        return 0 ;
    }
 
    if ((sd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror(NULL) ;
        return 2 ;
    }
 
    sa.sin_family = AF_INET ;
    sa.sin_port = htons(20000) ;
    sa.sin_addr.s_addr = htonl(INADDR_ANY) ;
    if (bind(sd, (struct sockaddr *)&sa, sizeof(sa)))
    {
        perror(NULL) ;
        close(sd) ;
        return 3 ;
    }
 
    if (listen(sd, 5)) return 4 ;
    printf("I start proxing\n") ;
 
    do {
        s = sizeof(ca) ;
        while ((cd = accept(sd, (struct sockaddr *)&ca, &s)) == -1) ;
        if (r = fork())
        {
            close(cd) ;
            if (r != -1) wait() ;
        }
        else
            if (fork())
            {
                close(cd) ;
                close(sd) ;
                return 0 ;
            }
            else    break ;
    } while (1) ;
 
    if ((pd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    {
        close(cd) ;
        close(sd) ;
        return 5 ;
    }
 
    pa.sin_family = AF_INET ;
    pa.sin_port = htons(20000) ;
    pa.sin_addr.s_addr = inet_addr("10.8.113.53") ;
    if (connect(pd, (struct sockaddr *)&pa, sizeof(pa)))
    {
        close(pd) ;
        close(cd) ;
        close(sd) ;
        return 6 ;
    }
 
    do {
        if ((r = recv(pd, buf, sizeof(buf), MSG_DONTWAIT)) == -1)
            { if (errno != EAGAIN) break ; }
        else
            if (r)
                { if (write(cd, buf, r) == -1) break ; }
            else    break ;
        if ((r = recv(cd, buf, sizeof(buf), MSG_DONTWAIT)) == -1)
            { if (errno != EAGAIN) break ; }
        else
            if (r)
                { if (write(pd, buf, r) == -1) break ; }
            else    break ;
    } while (1) ;
 
    close(pd) ;
    close(cd) ;
    close(sd) ;
    return 0 ;
}
Вроде бы прокси-сервер работает. Но при этом происходит эффект, смысла
которого я постичь не могу. Задумка была такая :
При старте родитель сделает fork() и тут-же завершится. Если его дочка успешно
начнет слушать порт 20000, то она сообщит I start proxing. Я предполагаю,
что этот первый fork() будет выполнен только один раз и I start proxing
появится только один раз. При обнаружении соединения дочка создаст внучку,
а та правнучку. Внучка завершится, а правнучка будет обслуживать соединение.
Дочка же будет ждать другого нового соединения. Такой двойной fork() сделан
для того чтобы избежать появления зомби и будет выполняться столько раз
сколько будет соединений.

Запускаю я это дело вот так :
nohup ./prox
И в файле nohup.out вижу странное. При каждом установлении соединения в нем
появляется строчка I start proxing. А при его разрыве вторая I start proxing.
А как такое может быть ? На то место в коде где выводится эта строчка
управление должно попасть только один раз при старте программы, а оно
попадает при каждом установлении соединения и при каждом разрыве.
Не могу этому найти логического объяснения. Или чего-то не понимаю.
Кто-нибудь подскажет верную мысль ?

Добавлено через 28 минут
P.S.
Поправил некорректность :
Code
1
2
3
4
5
6
7
8
9
10
11
Сравнение файлов prox.old и prox.c
***** prox.old
        do {
                s = sizeof(ca) ;
                while ((cd = accept(sd, (struct sockaddr *)&ca, &s)) == -1) ;
***** prox.c
        do {
                do
                        s = sizeof(ca) ;
                while ((cd = accept(sd, (struct sockaddr *)&ca, &s)) == -1) ;
*****
но все равно та-же херня.
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.02.2013, 21:25
Ответы с готовыми решениями:

Создает на n - уровне вложенный список, элементом которого на самом нижнем уровне является n
Я решил задачу так: CL-USER 1 &gt; (defun f (l n) (cond (( eq n 0) l) ((null l) (f (list n) (- n 1))) (t (f (cons...

LWP proxy ошибка Error: 407 Proxy authentication required
Есть скрипт: #!/usr/bin/perl use LWP::UserAgent; $ua = LWP::UserAgent-&gt;new; $ua-&gt;agent('Mozilla/9.0'); $ua-&gt;proxy('http'...

Proxy - выдает ошибку HTTP/1.0 407 PROXY AUTHENTICATION REQUIRED
что не так :angry: ? IdHTTP1.ProxyParams.ProxyServer :='прокси'; IdHTTP1.ProxyParams.ProxyPort :=порт; IdHTTP1.GET('URL'); ...

1
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
17.02.2013, 21:41
Буфер при выводе в файл по умолчанию не сбрасывается по переносу строки, поэтому "I start proxing" остаётся в нём(и наследуется дочерними) вплоть до завершения процесса.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.02.2013, 21:41
Помогаю со студенческими работами здесь

Прорыв через ISA proxy ошибку HTTP/1.1 407 Proxy Authentication Required
мой клиент на си++ по http протоколу общается с моим же сервром. Если на пути тупое прокси, то всё работает, но если через ISA - кабздец,...

WebReqest.Proxy, IE и WebBrowser proxy
господа, ситуация следующая: есть кусок кода, который создает запрос и получает ответ, потом этот ответ передает в WebBrowser и тогда уже...

поддомен на 3 уровне
Здравствуйте, интересует такой вопрос. У меня сайт на юкозе прикрепил к нему домен третьего уровня www.sait.org.ru могу ли я зделать на нём...

Простейший архиватор
Нужно написать простой архиватор. Который просто архивирует и разархивирует только файлы. Как его вообще писать?

Простейший фоторедактор c++
Необходим простейший фоторедактор, который имеет минимальный набор функций в виде накладывания фильтров, инверсии изображений, поворота...


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

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru