The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"C++ listen tcp socket"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 28-Сен-11, 03:20 
Здравствуйте!
Задача:
Создать приложение демон-процесс, слушающий и обрабатывающий запросы к TCP порту основанные на HTTP, выдающий в результате обработки запроса HTML-контент взятый из базы данных mysql, выполняющий перекодирование выдаваемого контента в желаемую/затребованную кодировку, которая устанавливается либо в самом запросе, либо в настройках его инициализационных параметров.
К сожалению, никогда не писал С++ программ для работы в сети, поэтому не представляю себе, что и в какой последовательности работает.
Я написал следующую программу:

int main (int argc, char * const argv[]) {
    struct sockaddr_in addr_info;
    int add_len = sizeof(addr_info);
    int ret_addr, sock_id;
    char* buf = new char[256];
    
    bzero(&addr_info, sizeof(addr_info));
    addr_info.sin_family = AF_INET;
    addr_info.sin_port = 8080;
    addr_info.sin_addr.s_addr = INADDR_ANY;

    sock_id = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_id==-1) {cout<< "Error create socket\n"; return -1;}
    if (bind(sock_id, (struct sockaddr*)&addr_info, sizeof(addr_info))==-1)  {cout<< "Error bind\n"; return -1;}
    listen(sock_id, 5);
    ret_addr = recv(sock_id, buf, 256, 0);
//    ret_addr = accept(sock_id, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
    return 0;
}

Но я так понимаю, что это совсем не в ту сторону. Единственное, что тут правильно - это socket().
Пожалуйста, подскажите схему приложения-реализации данной задачи, что за чем следует, а я постараюсь по Вашей схеме написать реализацию.
Заранее благодарен.
Алексей

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "C++ listen tcp socket"  +/
Сообщение от smb on 28-Сен-11, 08:49 
Это какой то выкидыш - огрызок тут даже половины нет
Вот курите тут по ссылкам ниже .............

http://www.gnu.org/s/hello/manual/libc/Server-Example.html#S...
http://www.w3.org/Protocols/rfc2616/rfc2616.html


>[оверквотинг удален]
>  ret_addr = recv(sock_id, buf, 256, 0);
> // ret_addr = accept(sock_id, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
>     return 0;
> }
> Но я так понимаю, что это совсем не в ту сторону. Единственное,
> что тут правильно - это socket().
> Пожалуйста, подскажите схему приложения-реализации данной задачи, что за чем следует,
> а я постараюсь по Вашей схеме написать реализацию.
> Заранее благодарен.
> Алексей

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 28-Сен-11, 10:08 
Спасибо.
Только мне кажется, что это не совсем то: тут реализована клиент-серверная модель (как и во всех других примерах), а мне надо, судя по условию задачи, что-то вроде tcpdump. Хотя я могу и ошибаться.
Такой вопрос: если я указываю программе 80 порт и у меня запущен веб-сервер, они не будут конфликтовать?
Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "C++ listen tcp socket"  +/
Сообщение от smb on 28-Сен-11, 10:25 
Если на разных машинках то не будут

> Спасибо.
> Только мне кажется, что это не совсем то: тут реализована клиент-серверная модель
> (как и во всех других примерах), а мне надо, судя по
> условию задачи, что-то вроде tcpdump. Хотя я могу и ошибаться.
> Такой вопрос: если я указываю программе 80 порт и у меня запущен
> веб-сервер, они не будут конфликтовать?

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 28-Сен-11, 10:42 
У мнея все на одной.
Значит, на время отладки веб-сервер выключить?
Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "C++ listen tcp socket"  +/
Сообщение от smb on 28-Сен-11, 10:44 
Ну выходит да
> У мнея все на одной.
> Значит, на время отладки веб-сервер выключить?
Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "C++ listen tcp socket"  +/
Сообщение от jd (??) on 29-Сен-11, 04:26 
> Только мне кажется, что это не совсем то: тут реализована клиент-серверная модель
> (как и во всех других примерах), а мне надо, судя по
> условию задачи, что-то вроде tcpdump.

Нет, ничего подобного. Вам как раз нужен самый обычный TCP сервер. Вообще, не очень понятно, зачем вам это писать. Всё уже давно написано: возьмите нормальный веб-сервер и пользуйтесь на здоровье.


> Такой вопрос: если я указываю программе 80 порт и у меня запущен
> веб-сервер, они не будут конфликтовать?

Прежде чем писать что-то на тему TCP/IP или даже просто использовать его, неплохо было бы почитать, что это вообще такое. Если вы даже не понимаете, что такое TCP порт, начните с чего-нибудь общего. Хоть бы и с википедии:
http://ru.wikipedia.org/wiki/%D0%9F%D0%B...(TCP/IP)

P.S. Нет совершенно ничего зазорного в том, что вы чего-то не знаете, ведь это можно сказать абсолютно про любого человека. Но не пытаться узнать что-то в наш век сверхдоступности информации - это по-моему тревожная тенденция. Желаю вам её исправить поскорее.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

7. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 29-Сен-11, 09:54 
Конечно оно так.
Насчет - зачем оно надо: это тестовое задание на знание взаимодействия С++ и сетей.
Насчет - знаю-незнаю - спорный вопрос: я, например, специализируюсь на администрировании сетей, но понятия не имею, как программа инициирует взаимодействие в сети и куда чего пишет.
Насчет документации - хороший вопрос: когда ее начинать читать? Я уверен, что не на этапе изучения предмета а в момент понимания логики работы пытаться постичь нюансы. Я не встречал документации, упрощающей понимание предмета изучения. Вы нигде в документации по ОС не найдете простого определение ядра ОС: на мой взгляд OC -  просто обработчик прерывания от таймера (в самом общем случае). Если человек поймет суть работы OC^ ему будет проще читать документацию про страшные менеджеры памяти и планировщики задач: он в уме уже будет представлять себе очереди потоков и понимание кода многопоточных приложений будет проще, если все представить на элементарном уровне.
По поводу TCP:
За два дня я получил много советов и ссылок, и каждый рассмотренный мною пример реализован по-разному. Все, что общего во всех примерах - это socket(). Далее набор функций варьируется от примера к примеру: bind, listen, connect,... Много хорошей документации по всем этим функциям, но нигде не написано, что происходит с пакетом, когда он попадает в лапы нашей неумелой программы. Так что пока моя программа похожа на слона в посудной лавке.
Меня утешает тот лишь факт, что Вы считаете эти вещи достаточно тривиальными - значит, в них просто разобраться. Я только пока не нашел, в чем соль...
Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "C++ listen tcp socket"  +/
Сообщение от pavlinux (ok) on 30-Сен-11, 22:06 
> я, например, специализируюсь на администрировании сетей, но понятия не имею,
> как программа инициирует взаимодействие в сети и куда чего пишет.

То есть, тот факт, что два разные программы, процессы, нити,..., не могут слушать
один и тот же порт, вам не известен?  Где Вы говорите админ, ну так на будущие,
чтоб на работу не брать оттуда?!

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

9. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 30-Сен-11, 22:57 
> То есть, тот факт, что два разные программы, процессы, нити,..., не могут
> слушать
> один и тот же порт, вам не известен?  Где Вы говорите

То что этого не умеет ванильный линукс, вовсе не значит, что этого не умеют другие системы.

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "C++ listen tcp socket"  +/
Сообщение от pavlinux (ok) on 01-Окт-11, 01:24 
>> То есть, тот факт, что два разные программы, процессы, нити,..., не могут
>> слушать
>> один и тот же порт, вам не известен?  Где Вы говорите
> То что этого не умеет ванильный линукс, вовсе не значит, что этого
> не умеют другие системы.

А одновременно?  Пёрнул, так раздувай...

А то ведь народ подумает, что Вы там на Inferno/Plan9,
иль мультеплесирование портов на полуаппаратных цисках.
иль мы в гугле нарыли флаги SO_REUSEADDR | SO_REUSEPORT ?


Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

11. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 01-Окт-11, 09:06 
> иль мы в гугле нарыли флаги SO_REUSEADDR | SO_REUSEPORT ?

Именно.
Ваш лузл пошел в коллекцию к:
>Так fork() возвращает PID потомка, который ты присваиваешь переменной pid.
>Далее он у тебя сравнивается с НОЛЁМ, НОЛЁВОЙ PID только у ЯДРА!!!!

(c)pavlinux     

Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

12. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 01-Окт-11, 11:31 
Насчет одновременного владения портом:
Конечно же, любой администратор (и даже полу-администратор, или же вообще типа-администратор) знает, что два так называемых "процесса" не могут одновременно слушать один и тот же порт. Да нам даже и знать не надо - система нам сама скажет, что порт уже слушается другим сервисом, и мы с Вами не раз это сообщение получали, из чего можем сделать логические выводы, что порт все-таки штука неделимая для процессов.
Теперь давайте посмотрим на ситуацию с другой стороны:
Допустим, веб-сервер слушает 80 порт. В то же время я могу "слушать" 80 порт tcpdump, а про netfilter я уже вообще молчу. Выходит, в самом общем случае нет процесса-монополиста порта. Все зависит от уровня в модели OSI ?
Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

13. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 04-Окт-11, 05:16 
Вот моя программа:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

int main (int argc, char * const argv[]) {
struct sockaddr_in addr_info;
int add_len = sizeof(addr_info);
int ret_addr, sock, n;
char* buf = new char[256];

     // socket
bzero(&addr_info, sizeof(addr_info));
addr_info.sin_family = AF_INET;
addr_info.sin_port = 80;
    addr_info.sin_addr.s_addr = inet_addr("127.0.0.1");//INADDR_ANY;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock==-1) {cout<< "Error create socket\n"; return -1;}
     // bind
if (bind(sock, (struct sockaddr*)&addr_info, sizeof(addr_info))==-1)  {cout<< "Error bind\n"; close(sock); return -1;}
    
     // listen
if (!listen(sock, 5)) {
    ret_addr = accept(sock, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
    n = read(ret_addr, buf, 255);
//    ret_addr = recv(sock, buf, 256, 0);
    cout << buf << "\n";
}
else {
    cout << "Error listen    ";
}
close(sock);
    
return 0;
}

Даже не могу сказать, что в ней не работает.
Если запускать в отладчике - то виснет на accept.
Если просто запустить - выполняется, ничего не происходит, не заканчивается.
Внутренний веб-сервер остановлен, обращаюсь к внутреннему хосту, а также к любому внешнему из браузера во время работы программы - ничего.
Когда мы указываем порт и адрес в структуре - их обязательно переводить функциями, или можно указать, как в моей программе?
И еще: как указать :
локальный хост?
конкретный хост?
Любой хост?
Пока все.

Ответить | Правка | ^ к родителю #12 | Наверх | Cообщить модератору

14. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 04-Окт-11, 10:32 
> addr_info.sin_port = 80;

addr_info.sin_port = htons(80);

>  n = read(ret_addr, buf, 255);
> // ret_addr = recv(sock, buf, 256, 0);
>  cout << buf << "\n";

Вам кто-то \0 в buf[n] пообещал?

> Даже не могу сказать, что в ней не работает.

Все работает, если найдете машину с сетевым порядком байт, то даже 80й порт слушать будет.

> Если запускать в отладчике - то виснет на accept.

попробуйте конектиться на 20480

> Когда мы указываем порт и адрес в структуре - их обязательно переводить
> функциями, или можно указать, как в моей программе?

Можно и как у вас (оно ж собирается и работает), но лучше функциями.
> И еще: как указать :
> локальный хост?

INADDR_LOOPBACK
> конкретный хост?

например как у вас
> Любой хост?

Если любой это все локальные адреса машины то у вас там правильная константа закомментирована или 0.0.0.0
А если любой это вообще любой, то линукс вроде не умеет делать bind() на чужие адреса, а в *BSD setsockopt с SO_BINDANY

Ответить | Правка | ^ к родителю #13 | Наверх | Cообщить модератору

15. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 04-Окт-11, 10:42 
>> addr_info.sin_port = 80;
> addr_info.sin_port = htons(80);

Если так, то bind выпадает, тогда уж htons(8080);
>> Если запускать в отладчике - то виснет на accept.
> попробуйте конектиться на 20480

Вы имеете ввиду, что порты ниже 1024 закрыты для пользовательских приложений?
>> И еще: как указать :
>> локальный хост?
> INADDR_LOOPBACK

Тут тоже bind выпадает

Я понимаю, что для полной реализации модели нужна клиентская часть, но я предполагаю, что моя программа услышит запрос из браузера 127.0.0.1:80 (или 8080)

Ответить | Правка | ^ к родителю #14 | Наверх | Cообщить модератору

16. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 04-Окт-11, 10:52 
>>> addr_info.sin_port = 80;
>> addr_info.sin_port = htons(80);
> Если так, то bind выпадает, тогда уж htons(8080);

Порт можете указать какой хочется... главное чтоб свободен был.

> Вы имеете ввиду, что порты ниже 1024 закрыты для пользовательских приложений?

Нет. Я хочу сказать что нужен сетевой порядок байт.

>> INADDR_LOOPBACK
> Тут тоже bind выпадает

Если он вам возвращает, что то отличное от EADDRINUSE или EACCES то приведите кусок кода и ошибку.

> предполагаю, что моя программа услышит запрос из браузера 127.0.0.1:80 (или 8080)

Услышит как только вы сделаете правильный bind() (я надеюсь вы браузер на этой же машине запускаете)

PS: прочитали бы вы какую-нибудь хорошую книжку.


Ответить | Правка | ^ к родителю #15 | Наверх | Cообщить модератору

17. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 04-Окт-11, 10:55 
Так, кое-что начинает проясняться.
указываем порт 8080, INADDR_ANY и из браузера стучимся localhost:8080 - получаем запрос от браузера.
Теперь как нам правильно указать 80 порт, чтобы bind не выпадал в -1, и мы могли стучаться просто localhost ?
Насчет свободных портов:
Если bind не хочет слушать 80 порт, значит его уже кто-то слушает?
Apache остановлен, кто еще может его держать и как посмотреть список слушающих процессов?
Ответить | Правка | ^ к родителю #15 | Наверх | Cообщить модератору

18. "C++ listen tcp socket"  +1 +/
Сообщение от guest email(??) on 04-Окт-11, 11:05 
> Теперь как нам правильно указать 80 порт, чтобы bind не выпадал в
> -1, и мы могли стучаться просто localhost ?

точно также как и 8080 или любой другой порт.
> Насчет свободных портов:
> Если bind не хочет слушать 80 порт, значит его уже кто-то слушает?

Или нет прав.

> Apache остановлен, кто еще может его держать и как посмотреть список слушающих
> процессов?

man netstat

Иди почитайте книжку, например Стивенса

Ответить | Правка | ^ к родителю #17 | Наверх | Cообщить модератору

19. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 04-Окт-11, 11:15 
Да, Вы правы - просто нет прав. Если запускать из-под sudo, то 80 порт слушает.
Насчет книжек и Стивенса, в частности, - читал, но бросил, потому, что даже самые элементарные примеры не работают. Теперь, после того, как заработал элементарный прием сообщений от браузера - можно и умной литературы немного почитать.
Ответить | Правка | ^ к родителю #18 | Наверх | Cообщить модератору

20. "C++ listen tcp socket"  +/
Сообщение от Вова on 04-Окт-11, 12:36 
> Да, Вы правы - просто нет прав. Если запускать из-под sudo, то
> 80 порт слушает.
> Насчет книжек и Стивенса, в частности, - читал, но бросил, потому, что
> даже самые элементарные примеры не работают. Теперь, после того, как заработал
> элементарный прием сообщений от браузера - можно и умной литературы немного
> почитать.

Что в примерах от Стивенса не заработало??

Ответить | Правка | ^ к родителю #19 | Наверх | Cообщить модератору

21. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 04-Окт-11, 12:51 
Нет, не заработало.
Еще вопрос:
Веб-браузер посылает запрос и мы должны ему ответить - послать страницу.
Я страницу посылаю так:
char* reply = "Content-type: text/html\n\n<HTML><BODY>\n<P>Hello!</P>\n</BODY></HTML>\n";
write(sock, reply, strlen(reply));

Но браузер ее не отображает.
1. Я не туда пишу.
2. Я не добавил заголовок к ответу типа: "HTTP 200 OK"

Ответить | Правка | ^ к родителю #20 | Наверх | Cообщить модератору

22. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 05-Окт-11, 10:00 
Здесь приведен участок кода, в котором программа слушает http-порт и читает данные, которые посылает ей браузер, если ему указать localhost, и затем делается попытка послать ответ браузеру (char* reply = "HTTP/1.1 403 Forbidden\r\n\0";)

if (!listen(sock, 5)) {
    ret_addr = accept(sock, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
    n = read(ret_addr, buf, 255);
    buf[255] = '\0';
    n = write(sock, reply, strlen(reply));
    cout << errno << endl;
    cout << buf << "\n";
}

чтение возвращает -1, errno=57 - Socket is not connected.
Что я делаю не так?

Ответить | Правка | ^ к родителю #21 | Наверх | Cообщить модератору

23. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 05-Окт-11, 11:08 
> Что я делаю не так?

Как минимум не проверяете, что вернул accept()

Ответить | Правка | ^ к родителю #22 | Наверх | Cообщить модератору

24. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 05-Окт-11, 15:21 
Хорошее выражение: "Смотрю в книгу и вижу..."
В read() я читаю из ret_addr, а писать пытаюсь в socket.
Ответить | Правка | ^ к родителю #23 | Наверх | Cообщить модератору

25. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 07-Окт-11, 13:31 
Теперь вопрос по процессам:
Предположим, я хочу, чтобы родительский процесс моей программы принимал запросы от клиентов (браузеров), и создавал для каждого из них дочерний процесс, который, в свою очередь, обрабатывал запрос и завершался, т.е.:

int main (int argc, char * const argv[]) {
sock = socket(AF_INET, SOCK_STREAM, 0);
bind(sock, (struct sockaddr*)&addr_info, sizeof(addr_info));
listen(sock, 1);
for (;) {
ret_addr = accept(sock, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
if (!fork()) { // child
close(sock);
// read
do {
n = read(ret_addr, buf, BUF_SIZE);
buf[n] = '\0';
cout << buf;
}
while (n==BUF_SIZE);
reply = "Child process: ";
out << getpid();
reply+= out.str();
n = write(ret_addr, reply.c_str(), reply.length());
if (errno) {perror("Errno: ");}
exit(0);
}
else { // parent
close(ret_addr);
}
}
close(sock);    
return 0;
}

Такая программа обрабатывает первый запрос нормально, второй запрос обрабатывает, но в errno записывает код ошибки Bad file descriptor, ну а третий запрос вообще не обрабатывает.
Что тут не так?

Ответить | Правка | ^ к родителю #24 | Наверх | Cообщить модератору

26. "C++ listen tcp socket"  +1 +/
Сообщение от jd (??) on 08-Окт-11, 11:50 
Ваш код неполон (как минимум, в нём есть необъявленные переменные) и к тому же содержит синтаксические ошибки. Проявите хоть каплю уважения к тем, к кому обращаетесь за помощью и не заставляйте их гадать, где же тут что имелось в виду и как же это "по идее" должно было бы работать. Выкладываете код, значит он должен компилироваться и работать, как вы описываете. И используйте тег [ code] (без пробела перед code), а то же совершенно невозможно это читать.

Касательно вашего творчества: трудно сказать, почему это не работает, потому что вы много чего делаете неправильно: не те проверки, не там проверки... Для начала это всё нужно переписать, а уж потом оллаживать.

P.S. Вам не показалось довольно странным, что так много людей упорно советуют вам что-нибудь почитать об этом всём? Не документацию (хотя это тоже нужно, конечно), а какую-нибудь книжку, учебник... Поверьте, это не совпадение.

P.P.S. И ради бога, переименуйте уже эту переменную ret_addr. Ну никакой это не адрес. Вводит же в заблуждение. Нельзя же переменные от балды называть.

Ответить | Правка | ^ к родителю #25 | Наверх | Cообщить модератору

27. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 08-Окт-11, 12:01 
Да я пытился читать Стивенса - говорю же Вам, что на первом же примере засыпался. Я не могу и не умею читать книжки. Я все пытаюсь написать руками - на что трачу много ненужного времени.
Код исправлю, в теги буду  писать  на будущее.
В данном примере хотел представить идею разделения процессов: кто куда идет - код не компилируем, все убрал из него только чтобы общую картину показать.
Мне дали совет использовать библиотеку boost.asio - но я не могу слинковать libboost_system
Ответить | Правка | ^ к родителю #26 | Наверх | Cообщить модератору

28. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 13-Окт-11, 10:55 
Как ни прискорбно - но  с boost у меня тоже не срослось.
Итак, вернемся к самописному варианту tcp-сервера.
Как утверждает Стивенс (и не зря утверждает), "сервер" начинает слушать протокол и порт, который мы ему "натравили":
listen();
И далее принимает(или "засыпает", если очередь входящих сообщений пуста) входящие запросы от "клиента" (в нашем случае - веб-браузера):
accept();

(Дальше мои мысли)
Следовательно, как только accept() вернул нам валидный дескриптор:
if ( (session=accept(socket, buf, buf_len))!=-1 ) {/*valid handler*/}
мы можем создавать дочерний поток(процесс), который обработает запрос и завершится:


listen();
for (;;) {
accept();
if ( (session=accept(socket, buf, buf_len))!=-1 ) {
if(!fork()) {/*child*/do smth; exit(0);}
else        {/*parent*/ close(session);}
}
}

Теперь скажите мне, почему session закрывается родителем?
Я, конечно, ноль в многопоточности, однако из прочитанной мной литературы о процессах сделал вывод, что с момента
fork()
и родитель, и его потомок начинают работать одновременно в одном и том же адресном пространстве (за последнее не ручаюсь). Как же потомок сможет читать/писать в session, если родитель, согласно логике программы, сразу же закроет дескриптор?
Подскажите, пожалуйста, в каком месте нарушена логика?

Ответить | Правка | ^ к родителю #27 | Наверх | Cообщить модератору

29. "C++ listen tcp socket"  +/
Сообщение от Вова on 15-Окт-11, 09:56 
>[оверквотинг удален]
>
> Теперь скажите мне, почему session закрывается родителем?
> Я, конечно, ноль в многопоточности, однако из прочитанной мной литературы о процессах
> сделал вывод, что с момента
> fork()
> и родитель, и его потомок начинают работать одновременно в одном и том
> же адресном пространстве (за последнее не ручаюсь). Как же потомок сможет
> читать/писать в session, если родитель, согласно логике программы, сразу же закроет
> дескриптор?
> Подскажите, пожалуйста, в каком месте нарушена логика?

вы невнимательно читали Стивенса. У дескриптора есть счётчик ссылок, соединение будет закрыто по закрытию последнего дескриптора, ссылающегося на это соединение. Адресное пространство после форк скопировано от родителя, но не одно и то же, табличка с влиянием форк/ехес/ехit на дескрипторы/мутексы/етс также приведена у Стивенса.

Ответить | Правка | ^ к родителю #28 | Наверх | Cообщить модератору

30. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 15-Окт-11, 15:53 
Если честно - я его вообще не читал. Но раз Вы утверждаете, что у него есть описание взаимодействия процессов с дескрипторами, я обязательно посмотрю, что он пишет.
Из прослушанных мною лекций по многопоточности я тоже сделал умозаключение, что используется счетчик ссылок, но не был в этом уверен. Теперь Вы укрепили меня в моем мнении. Спасибо.
Ответить | Правка | ^ к родителю #29 | Наверх | Cообщить модератору

33. "C++ listen tcp socket"  +/
Сообщение от Вова on 15-Окт-11, 20:49 
> Если честно - я его вообще не читал. Но раз Вы утверждаете,
> что у него есть описание взаимодействия процессов с дескрипторами, я обязательно
> посмотрю, что он пишет.
> Из прослушанных мною лекций по многопоточности я тоже сделал умозаключение, что используется
> счетчик ссылок, но не был в этом уверен. Теперь Вы укрепили
> меня в моем мнении. Спасибо.

Закрытие дескрипторов при создании дочернего процесса для каждого соединения описано в  главе про разработку серверных приложений по различным моделям книги "Разработка сетевых приложений UNIX", табличка с влиянием fork/exec/exit на различные ресурсы в отдельном труде "Взаимодействие процессов UNIX".

Ответить | Правка | ^ к родителю #30 | Наверх | Cообщить модератору

31. "C++ listen tcp socket"  +/
Сообщение от superuser on 15-Окт-11, 20:30 
ребят, ну откуда вы такие беретесь.
не можете читать книжки, смотрите примеры.
http://tinyhttpd.cvs.sourceforge.net/viewvc/tinyhttpd/tinyht...
Ответить | Правка | ^ к родителю #13 | Наверх | Cообщить модератору

32. "C++ listen tcp socket"  +/
Сообщение от superuser on 15-Окт-11, 20:36 
> ребят, ну откуда вы такие беретесь.
> не можете читать книжки, смотрите примеры.
> http://tinyhttpd.cvs.sourceforge.net/viewvc/tinyhttpd/tinyht...

читать книжки мы не умеем, пользоваться гуглом тоже http://stackoverflow.com/questions/176409/how-to-build-a-sim...


Ответить | Правка | ^ к родителю #31 | Наверх | Cообщить модератору

39. "C++ listen tcp socket"  +/
Сообщение от mesmeridze (ok) on 20-Окт-11, 17:44 
>> То есть, тот факт, что два разные программы, процессы, нити,..., не могут
>> слушать
>> один и тот же порт, вам не известен?  Где Вы говорите
> То что этого не умеет ванильный линукс, вовсе не значит, что этого
> не умеют другие системы.

А кто умеет то? Я ничо мне интересно просто...

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

40. "C++ listen tcp socket"  +/
Сообщение от guest email(??) on 20-Окт-11, 21:12 
> А кто умеет то? Я ничо мне интересно просто...

Как минимум все BSD семейство и AIX, ну и если верить манам HPUX (сам про него хз)

Ответить | Правка | ^ к родителю #39 | Наверх | Cообщить модератору

41. "C++ listen tcp socket"  +/
Сообщение от Аноним (??) on 27-Окт-11, 05:42 
>> А кто умеет то? Я ничо мне интересно просто...
> Как минимум все BSD семейство и AIX, ну и если верить манам
> HPUX (сам про него хз)

Чёто ты кривого чешешь! :)Ссылочку кинь?

Ответить | Правка | ^ к родителю #40 | Наверх | Cообщить модератору

34. "C++ listen tcp socket"  +/
Сообщение от fisher (??) on 16-Окт-11, 22:16 
>[оверквотинг удален]
>  ret_addr = recv(sock_id, buf, 256, 0);
> // ret_addr = accept(sock_id, (struct sockaddr*)&addr_info, (socklen_t*)&add_len);
>     return 0;
> }
> Но я так понимаю, что это совсем не в ту сторону. Единственное,
> что тут правильно - это socket().
> Пожалуйста, подскажите схему приложения-реализации данной задачи, что за чем следует,
> а я постараюсь по Вашей схеме написать реализацию.
> Заранее благодарен.
> Алексей

https://www.opennet.ru/docs/RUS/linux_parallel/node76.html

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

35. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 17-Окт-11, 15:05 
Теперь встал еще один вопрос: Как отправить заголовок браузеру? Т.е.:
в php ч/з header(), а в с++ - ?
Начнем с самого простого, без чего, якобы, браузер вообще не сможет прочитать содержимое ответа (но, тем не менее, читает) - Content-length:

string str = "<html>...</html>";
string reply = "Content-length: "+str.length();
reply+= "\r\n\r\n"; // end of header
reply+= str;

Здесь все отлично - браузер отображает содержимое документа, причем сам заголовок в теле документа не отображается.
Далее хочу отправить кодировку в документ, т.к. документ у меня в cp-1251, а браузер - в utf-8 (default):
Какой же параметр устанавливает кодировку в заголовке?
google.com -> http header rfc -> http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Читаю:
14.2 Accept-Charset
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
14.17 Content-Type
Content-Type: text/html; charset=ISO-8859-4
Пишу:

string str = "<html>...</html>";
string reply = "Accept-Charset: cp-1251"; //string reply = "Content-Type: text/html; charset=cp-1251";
reply+= "\r\n\r\n"; // end of header
reply+= str;

Ни один из этих вариантов браузер не считает за заголовки и выводит их в основное тело документа.
Как правильно и какие заголовки посылать браузеру?
Ответить | Правка | ^ к родителю #34 | Наверх | Cообщить модератору

36. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 18-Окт-11, 15:32 
Проблемы с кодировкой наблюдались у меня в случае, когда я делал так:

wget google.com/index.html
И далее использовал полученный файл, как документ.
Если же я самостоятельно напишу документ в текстовом редакторе по всем правилам указания кодировок - таких проблем не возникает.

Теперь усложним задачу:
Для начала заметим, что значение дескриптора socket и accept в программе:
sock = socket(...);//4
session = accept(sock, ...); // 5

Теперь  запустим нашу программу как демон из другой програмы:
if(!fork()) execl("myprog", argv);

Наша программа успешно запустилась и ждет входящих сообщений, но не обрабатывает их (т.е. по-просту, не работатет).
И почему-то указанные выше sock и session на 1 меньше:
sock = socket(...);//3
session = accept(sock, ...); // 4

Что тут не так?

Ответить | Правка | ^ к родителю #35 | Наверх | Cообщить модератору

37. "C++ listen tcp socket"  +/
Сообщение от Вова on 18-Окт-11, 22:31 

> И почему-то указанные выше sock и session на 1 меньше:
> sock = socket(...);//3
> session = accept(sock, ...); // 4
> Что тут не так?

да, а ведь должно быть меньше на три дескриптора, ведь это демон.

Ответить | Правка | ^ к родителю #36 | Наверх | Cообщить модератору

38. "C++ listen tcp socket"  +/
Сообщение от handler2006 (ok) on 19-Окт-11, 13:10 
Неправильный подход к реализации: я запускал процесс из другой программы, а все делается проще:


int main () {
if (fork()) exit(0);
/* daemon code here*/
return 0;
}

Ответить | Правка | ^ к родителю #37 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру