Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нужна помощь, При работе с сокетами Windows 
:(
    Опции темы
vikaz
Дата 16.12.2008, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



Всем добрый день!
Передо мной поставили задачу написать клиент-серверное приложение, обменивающиеся данными через интернет. Есть клиентское приложение, которое отправляет на сервер текстовые сообщения, являющиеся по сути командами, а также графику (bmp, jpg, gif). Сервер получает данную строку и формирует из нее SQL запрос, данный запрос отправляется базе MySQL, которая отрабатывает данный запрос и возвращает данные, которые переправляются обратно клиенту. Клиент их визуализирует. Примерное количество клиентов, которые будут подключаться к серверу равно 1000 (это примерно). Пишу на с++ Builder 2009.
Сначала я думал писать при помощи Indy, но ребята меня переубедили, что этого не стоит делать, а лучше написать транспортный модуль самому. Под транспортным модулем я подразумеваю не новый протокол обмена данными по сети, а так сказать интерфейс работающий с TCP/IP протоколом.
Почитав литературу и порывшись на сайтах, нашел много информации и методов работы с TCP/IP, НО НА КАКОМ ОСТАНОВИТЬСЯ не знаю. Поэтому и прошу у Вас помощи.
Вот основные методы для работы с TCP/IP протоколом:
1. Блокирующий(синхронный) сокет.
2. Не блокирующий (асинхронный) сокет.

Для нормальной работы первого метода, создаются потоки, при подключении нового клиента к серверу. Как мне кажется плюс этого метода, что одна на писаная функция работы с клиентом и каждый раз запускаемая в потоке решает  все задачи, которые я пропишу. Но вопрос, не накладно ли будет для железа создавать 1000 потоков, разгребет ли, и есть ли смысл и целесообразно ли? Но есть и большой минус. Допустим, что был вызов функции recv, но по каким-то причинам она не вернула данные. В этом случае она останется заблокированной навечно, и сервер больше не будет реагировать на действия пользователя.

Второй метод более гибкий, но он и труднее в программировании и лишен выше описанной проблемы.
Для асинхронных соке тов так же можно выделить несколько методов:
1. Использование массива соке тов и с использованием select
2. Использование соке тов через события windows
3. Асинхронная работа через объекты событий.

Описывать +/- каждого метода долго. Но вся проблема, для меня, упирается в то, как использовать асинхронные сокеты 2 и 3 для 1000 подключенных, как отслеживать, от кого пришла стока и кому ответить (для всех трех методов).

И ко всему этому остается проблема правильности доставки сообщений, не факт, и это известно, что данные придут сразу все. Могут придти не все, а если сообщения маленькие, то они могут придти сразу оба. Как при использовании асинхронного сокета учесть это и при синхронном тоже?
Надеюсь не утомил. smile 
Очень нужна помощь, направьте на путь истинный! smile
Заранее спасибо.


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
J0ker
Дата 17.12.2008, 05:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



не изобретайте велосипед
используете паттерн реактор
кол-во потоков = кол-во ядер * 2
для винды используете completion ports, для *nix - пулы - если есть, select - если пулов нет - оптимально можно заюзать boost::asio - там использование этих фич скрыто в классах


--------------------
user posted image
PM MAIL   Вверх
vikaz
Дата 17.12.2008, 07:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



J0ker, можно подробнее. Много "красивых" слов. Но пока они мне не все понятны. smile


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Cтpaнник
Дата 17.12.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 12.10.2008
Где: Россия, Санкт-Пет ербург

Репутация: нет
Всего: нет



PM MAIL   Вверх
vikaz
Дата 17.12.2008, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



Cтpaнник, не могу с этого сайта ничего скачать. Можешь скинуть скаченные архивы, благо они весят не много. + ссылочку на описание IOCP. не могу найти русскоязычного описания! Заранее спасибо!


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Олег2005
Дата 17.12.2008, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Тут найдете основное:

Присоединённый файл ( Кол-во скачиваний: 16 )
Присоединённый файл  IOCP.zip 51,81 Kb
PM MAIL WWW MSN   Вверх
Cтpaнник
Дата 17.12.2008, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 12.10.2008
Где: Россия, Санкт-Пет ербург

Репутация: нет
Всего: нет



vikaz, там чтобы что-то скачивать (архивы, примеры и т.п.) просто надо зарегистрироваться. Это бесплатно smile
PM MAIL   Вверх
J0ker
Дата 17.12.2008, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(vikaz @ 17.12.2008,  07:19)
J0ker, можно подробнее. Много "красивых" слов. Но пока они мне не все понятны. smile

паттерн многопоточный реактор - создаете пул потоков которые сидят на ожидании (лучше организовать LIFO)
в случае пулов и completion ports - когда приходит сообщение первый свободный поток из очереди его подхватывает и вызывает соответствующий обработчик
в случае использования select - диспетчер подхватывает сообщение, и соответственно типу передает его потоку инициализированному конкретным обработчиком
по поводу кол-ва потоков в пуле
обычно бессмысленно держать в работе больше потоков, чем имеется ядер
но учитывая особенности например completion ports, надо иметь под рукой запасные потоки, т.к. при попадании работающего потока в операцию, вызывающую какую-либо wait функцию, система считает, что можно запустить еще один поток.
т.о. все зависит от того, что делает обработчик - если это голые вычисления, допустим, где гарантированно нет wait вызовов, то можно ограничится кол-вом потоков равным кол-ву ядер, если-же есть обращение, например, к удаленной базе данных с длительными ожиданиями - то здесь нужно увеличить кол-во потоков в пуле больше чем 2*кол-во ядер
можно попробовать сделать динамический пул - если запущеный поток последний в пуле, то создается еще один - т.е. пул никогда не бывает пустым, если-же поток не запускался определенное время, то он уничтожается - по идее для LIFO эта тактика должна быть довольно эффективна...

ЗЫЖ да, и посмотрите все-таки boost::asio - возможно это как раз то, что вам нужно



--------------------
user posted image
PM MAIL   Вверх
vikaz
Дата 18.12.2008, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



Ребята, всем огромное спасибо, буду смотреть и разбираться. Олег2005 и тебе спасибо за файл. smile 


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
vikaz
Дата 18.12.2008, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



Олег2005, это вырезка, а откуда? Если не секрет.....


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Олег2005
Дата 18.12.2008, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Это из моего учебника по сетевому программированию smile 
PM MAIL WWW MSN   Вверх
MAKCim
Дата 18.12.2008, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207





--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
vikaz
Дата 18.12.2008, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



MAKCim спс, за ссылку. Олег2005 и много у тебя там такого интересного? Можно ли как-то её почитать?


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
vikaz
Дата 19.12.2008, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: нет
Всего: 12



Олег2005, спасибо еще раз за инфу. Но у меня по ней возникли вопросы. А именно к серверной части, так как в клиентской все просто.

Вопросы:
1. В фунции main в конце есть сл. код:

Код

//Добавляем клиента в список
ClientList.insert(ClientList.end(),client);
// Создаем overlapped-структуру 
ovpConnection * op = new ovpConnection;
//Заполняем overlapped-структуру 
op->sock_handle = client;
op->op_type = ovpConnection::op_type_recv;
op->buffer = new char[BUFF_SIZE];
op->hEvent = 0;
op->client_number=++ClientCount;
strcpy(buffer,"Клиент № %d подключился, активных клиентов %d\n");
CharToOem(buffer,buffer);
printf(buffer,ClientCount,ClientList.size());
unsigned long b;
WSABUF buf;
buf.buf = op->buffer;
buf.len = BUFF_SIZE;
flags=0;
err=WSARecv(op->sock_handle, &buf, 1, &b, &flags, op, 0);
if(!err)
{
   strcpy(buffer,"Ошибка ф-ции WSARecv");
   CharToOem(buffer,buffer);
   printf("%s %d\n",buffer, WSAGetLastError());
}


Сам вопрос, зачем в конце сл. строки? 
Код

unsigned long b;
WSABUF buf;
buf.buf = op->buffer;
buf.len = BUFF_SIZE;
flags=0;
err=WSARecv(op->sock_handle, &buf, 1, &b, &flags, op, 0);
if(!err)
{
   strcpy(buffer,"Ошибка ф-ции WSARecv");
   CharToOem(buffer,buffer);
   printf("%s %d\n",buffer, WSAGetLastError());
}

Что ты пытаешься тут отправить. Как мне показалось, ты просто ошибся и я убрал эти строки.
Но Код так и не заработал. Точнее часть. Сервер показывает, что клиент подключился, но сообщения не принимает и не отправляет! :(
еще возник вопрос, в структуре мы не вводили данный параметр, но он присутствует:
op->hEvent = 0;

Это сообщение отредактировал(а) vikaz - 19.12.2008, 09:18


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Олег2005
Дата 19.12.2008, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Посмотрите вот  здесь
Там есть кое-какие комментарии.
Цитата

Что ты пытаешься тут отправить.

Да нет, там не отправка - а прием от клиента - WSARecv
Цитата(vikaz @  19.12.2008,  07:52 Найти цитируемый пост)
op->hEvent = 0;

Это поле из структуры OVERLAPPED, которая включена в структуру ovpConnection, и его имя - hEvent - по умолчанию.

И еще - в функцию void SendToAll(char *buffer,unsigned long bytes) тоже надо добавить 
op->hEvent = 0;

Это сообщение отредактировал(а) Олег2005 - 22.12.2008, 23:26
PM MAIL WWW MSN   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0976 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.