Страниц: [1]
  Печать  
Автор Тема: Proxy & Socket  (Прочитано 7730 раз)
dante
Гость
« : Мая 14, 2003, 03:07:00 pm »

Хочу чтобы мой процесс получал сообщение при наличии данных для считывания из сокета.
Смотрел пример selio... Помогите разобраться плз...
Там сделано примерно так:
sock = socket(AF_INET, SOCK_STREAM, 0);
...
//Если у меня сокет менеджер локальный то можно этого не делать?
qnx_fd_query(0, 0, sock, &fd_info);
rem_readproxy= qnx_proxy_rem_attach(fd_info.nid, readproxy) ;
...
connect(sock, (struct sockaddr *)&server, sizeof(server)));
...
//Это нужно? Не делал...
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) ;
...
struct _io_select r ;
...
r.proxy= rem_readproxy ; //тут ставил readproxy
...
Sendfdmx(sock, 2, 2, mx, mx) == -1)
...
pid=Receive(0,0,0);
if(pid==rem_readproxy)read(sock ...

У меня немного другой случай:
sock = socket(AF_INET, SOCK_STREAM, 0);
listen(sock)
sock2=accept(sock)
Должен-ли этот механизм работать если, начиная со строчки fcntl ... я буду подставлю sock2?
Я подставил - не работает .


Записан
klalafuda
QOR.Team
****
Offline Offline

Сообщений: 1


Просмотр профиля
« Ответ #1 : Мая 14, 2003, 03:15:00 pm »


dante пишет:
Хочу чтобы мой процесс получал сообщение при наличии данных для считывания из сокета.
Смотрел пример selio... Помогите разобраться плз...
Там сделано примерно так:
sock = socket(AF_INET, SOCK_STREAM, 0);
...
//Если у меня сокет менеджер локальный то можно этого не делать?
qnx_fd_query(0, 0, sock, &fd_info);
rem_readproxy= qnx_proxy_rem_attach(fd_info.nid, readproxy) ;
...
connect(sock, (struct sockaddr *)&server, sizeof(server)));
...
//Это нужно? Не делал...
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) ;
...
struct _io_select r ;
...
r.proxy= rem_readproxy ; //тут ставил readproxy
...
Sendfdmx(sock, 2, 2, mx, mx) == -1)
...
pid=Receive(0,0,0);
if(pid==rem_readproxy)read(sock ...

У меня немного другой случай:
sock = socket(AF_INET, SOCK_STREAM, 0);
listen(sock)
sock2=accept(sock)
Должен-ли этот механизм работать если, начиная со строчки fcntl ... я буду подставлю sock2?
Я подставил - не работает .


рабочий пример посылки _IO_SELECT и иже с ним на сокет есть на QUICS (http://ftp://ftp.qnx.com/usr/free/...).

лично мой совет: баловство это все. проект усложняет изрядно, надежность падает, а полезностей ровно ноль. если руки не кривы, поигравшись, все равно вернетесь к разбиению системы на набор синхронно исполняющихся процессов т.е. к классической fork() схеме. или к многопоточности, но это уже QNX6.

ps: про переносимость подобный ухищрений в стиле QNX4 я уж и не говорю..

// wbr
Записан
dante
Гость
« Ответ #2 : Мая 14, 2003, 04:28:00 pm »


klalafuda пишет:
рабочий пример посылки _IO_SELECT и иже с ним на сокет есть на QUICS (http://ftp://ftp.qnx.com/usr/free/...).

Это selio.c.gz и есть. Кажется.

лично мой совет: баловство это все. проект усложняет изрядно, надежность падает, а полезностей ровно ноль. если руки не кривы, поигравшись, все равно вернетесь к разбиению системы на набор синхронно исполняющихся процессов т.е. к классической fork() схеме. или к многопоточности, но это уже QNX6.

Например,
Процесс перенаправляющий данные из socket в /dev/ser1 и обратно. (с небольшой обработкой).
я думал так делать (и раньше подобное так и делал):
while ((pid=Receive())!=-1){
if (pid==socket){
 s=read(fsocket.data,size);
 process1(data);
 write(fser,data,s);
}else if(pid==serial){
 s=read(fserial,data,size);
 process2(data);
 write(fsocket,data,size);
}
Если через fork ... Это так что-ли(просто интересно я долго только под win программировал и fork вообще редко использую):
if ((child=fork())==0){
 while(1){
   s=read(fsocket.data,size);
   process1(data);
   write(fserial,data,s);
 }
}else if(child>0){
 while(1){
   s=read(fserial,data,size);
   process2(data);
   write(fsocket,data,size);
 }
}
Но так ведь обьем требуемой памяти удваивается!
А общие переменные? В shared memory? Но тогда и процессы надо синхронизировать, семафоры использовать.
Записан
klalafuda
QOR.Team
****
Offline Offline

Сообщений: 1


Просмотр профиля
« Ответ #3 : Мая 14, 2003, 04:53:00 pm »


dante пишет:

klalafuda пишет:
рабочий пример посылки _IO_SELECT и иже с ним на сокет есть на QUICS (http://ftp://ftp.qnx.com/usr/free/...).

Это selio.c.gz и есть. Кажется.

лично мой совет: баловство это все. проект усложняет изрядно, надежность падает, а полезностей ровно ноль. если руки не кривы, поигравшись, все равно вернетесь к разбиению системы на набор синхронно исполняющихся процессов т.е. к классической fork() схеме. или к многопоточности, но это уже QNX6.

Например,
Процесс перенаправляющий данные из socket в /dev/ser1 и обратно. (с небольшой обработкой).
я думал так делать (и раньше подобное так и делал):
while ((pid=Receive())!=-1){
if (pid==socket){
 s=read(fsocket.data,size);
 process1(data);
 write(fser,data,s);
}else if(pid==serial){
 s=read(fserial,data,size);
 process2(data);
 write(fsocket,data,size);
}
Если через fork ... Это так что-ли(просто интересно я долго только под win программировал и fork вообще редко использую):
if ((child=fork())==0){
 while(1){
   s=read(fsocket.data,size);
   process1(data);
   write(fserial,data,s);
 }
}else if(child>0){
 while(1){
   s=read(fserial,data,size);
   process2(data);
   write(fsocket,data,size);
 }
}
Но так ведь обьем требуемой памяти удваивается!
А общие переменные? В shared memory? Но тогда и процессы надо синхронизировать, семафоры использовать.


берем Робачевского, "UNIX", читаем. там все есть.

// wbr
Записан
kors
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля
« Ответ #4 : Июня 30, 2003, 08:38:00 pm »


dante пишет:
Хочу чтобы мой процесс получал сообщение при наличии данных для считывания из сокета.



совсем не сложно использовать отдельный процесс и select()  =)
Записан
Gandrew
Участник
*
Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #5 : Ноября 01, 2013, 11:24:04 am »

Здравствуйте уважаемые посетители. Если у кого есть архив с примеро selio, могли бы Вы скинуть его по почте или дать ссылочку, где можно скачать. ftp.qnx.com почему-то недоступен.
Записан
Gandrew
Участник
*
Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #6 : Ноября 01, 2013, 01:13:08 pm »

Опишу проблему,может есть кто-то, кто  сможет мне помочь.
Написал простой сервер с использованием _beginthread вместо fork. Проблема в следующем : если подключается к серверу 2 и более клиентов, в системе то начинает расти количество созданых прокси.Через несколько минут оно доходит до максимума и система ничего не может выполнить, выдавая сообщение о том,что ресурсы заняты. Как только я закрываю клиенты, оставив работать только один, то потоки, которые их обрабатывали, количество прокси в системе приходит в норму. Если закоментировать select/ то прокси не создаются, но в то же время работает бесконечный цикл,что не есть хорошо.
 Буду благодарен любым сосветам, которые направят в нужно русло.

PS: Надеюсь, я понятно описал проблему. _begin_thread использую намерено, т.к. есть общие данные между потоками и не хочется создавать в системе лишний shmem.
« Последнее редактирование: Ноября 01, 2013, 05:04:57 pm от Gandrew » Записан
PoP
Sr. Member
****
Offline Offline

Сообщений: 336


Просмотр профиля
« Ответ #7 : Ноября 02, 2013, 02:12:37 am »

Если всё работает корректно, в 4-ке должно быть практически всё равно, что использовать - fork+shared memory или  _begin_thread. В 4-ке нет сущности "нить",  _begin_thread создаёт такойже равноправный процесс, как и fork.
Обычно прокси в системе начинают копиться при перегрузке (ну, или если их никто не выгребает). По умолчанию, их в системе может быть не так много. Прокся - такойже процесс, как и все остальные, а всего в системе по умолчанию может существовать 500 процессов (вроде так, может что забыл). При активном использовании фунций с автоматическими таймаутами (создают таймеры и, следовательно прокси) или оповещениями ресурсы быстро заканчиваются (да ещё если это дело иногда начинает копиться в очередях...). Если это происходит только в момент кратковременной критической нагрузки на систему мжно попробовать пересобрать ядро, указав Proc32 через непомню какой ключик новое максимальное число процессов.
« Последнее редактирование: Ноября 02, 2013, 02:15:34 am от PoP » Записан
Gandrew
Участник
*
Offline Offline

Сообщений: 11


Просмотр профиля
« Ответ #8 : Ноября 02, 2013, 11:32:35 am »

ДА! Всё,что Вы написали, верно. Но меня смущают два момента - это то,что нагрузка минимальная ( 2-3 клиента при частоте опроса 1 секунда )и при использовании fork никакие proxy не накапливаются. Что-то мне подсказывает,что придётся всё таки делать через связку fork + shmem.
 
« Последнее редактирование: Ноября 04, 2013, 10:44:37 am от Gandrew » Записан
Basil-64
Sr. Member
****
Offline Offline

Сообщений: 282



Просмотр профиля
« Ответ #9 : Ноября 08, 2013, 06:31:24 pm »

Ребята, вы о чем? Классикой для 4-ки является то, что прокси для толчка создается сервером, то есть процессом, который надо толкнуть. О каком росте числа прокси в системе тогда может идти речь? А вот если создаете прокси в клиенте на сервер, то уж озаботьтесь механизмами регулирования нагрузки на сей сервер, дабы он успевал разгребать свои входные очереди и детачить прокси.
Записан

В жизни всегда есть место подвигу - главное быть подальше от этого места. Но никак не получается.
PoP
Sr. Member
****
Offline Offline

Сообщений: 336


Просмотр профиля
« Ответ #10 : Ноября 09, 2013, 11:12:57 am »

Как раз, в данном случае, "надо толкнуть" (с) клиентский (по отношению к сетевому стеку) процесс. Например в случае с dev_read() клиент сам явно создаёт proxy, ну а в случае с select() за него это делает библиотека (ну или сервер по просьбе библиотеки).  Видимо fork() и _begin_thread() используют разные механизмы (или разные умолчания) дублирования файловых дескрипторов при порождении потока (я предполагаю что select() слушает порты и затем для каждого клиента порождается новый поток). В отличии от 6-ки, в 4-ке _begin_thread() создаёт процесс, и, вроде, должна (как и fork()) продублировать в новом процессе все открытые дескрипторы (со всеми связанными с ними проксями - тут я уже не очень понимаю зачем и вобще должно ли это делаться). Так что при росте числа клиентов покси будут размножаться. Ели при перегрузке системы внешний клиент не получив вовремя ответа на запрос о подключении (соответстствующий поток только создаётся или не успел ответить) пошлёт следующий запрос то (если нет соответствующих проверок) всё будет расти лавинообразно.
Записан
Страниц: [1]
  Печать  
 
Перейти в: