Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Несколько вопросов по сетевому программированию на С++ (азы)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Это упущение есть, но до него, из-за проблемы коннекта, дело ещё не дошло.
 
Вот скрин, на котором отображена попытка коннекта...
 
Подробнее...
 
Кстати, спасибо за терпение и внимание, я думал будет совсем подругому...
 
Добавлено:
Поискал инфу по нету и выяснил, что даже если WSAConnec(...) = SOCKET_ERROR и при этом WSAGetLastError() возвращает 10035, то ещё не значит, что нету коннекта. В моём случае WSAConnec(...) устанавливает соединение в "скрытом" режиме.
 
Написал лесенку событий, отслеживание оных и вывод текста при их срабатывании.
 
Перед лесенкой воткнул:
WSAEnumNetworkEvents(s,sEvent,&NetEvent);
 
В каждый блок лесенки вписал строку:
printf("%s%i\n","Event id = ",NetEvent.lNetworkEvents);
 
И начлись чудеса!... При срабатывании события FD_CONNECT получаю текст в консоль:
Event Id = 18
(именно 18, не очепятка, при том, что FD_CONNECT = 16, а следующий по возрастанию только FD_CLOSE = 32)
 
Выбегаю опять инет, лажу по форума и статьям. Результат один - нету такого эвента.
 
Я даже не знаю что спросить, просто в недоумении.

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 23:27 15-01-2011 | Исправлено: Wc3Exp, 23:32 15-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Это упущение есть, но до него, из-за проблемы коннекта, дело ещё не дошло.
Как раз до него и дошло. Когда клиент коннектится на слушающий сокет, создается новый сокет, который передается новому потоку, который будет далее обслуживать это соединение. Но потоку передается вместо сокета полная ерунда, и соединения как такового не возникает.
Кстати, в Вижуал Студио имеется встроенный дебаггер, с помощью которой можно отслеживать выполнение программы по шагам. В том числе проследить значения переменных, передающихся и получаемых другими потоками. Рекомендую воспользоваться.


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 15:14 16-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Всё дело было в WSARecv и WSASend (обе возвращали -1)... Заменил из на обычные recv и send и вновь связь наладилась (клиент принимает пересылку сервера при коннекте).
 
Осталось неясным как передать сообщение на сервер и как принять его на сервере. На какой порт и сокет посылать?  
Клиент "знает" только адрес слушающего серверного порта и не имеет понятия о новом созданном сокете.
 
Как организовать пересылку данных на сервер?

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 19:00 16-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp
Цитата:
Как организовать пересылку данных на сервер?
Тот же сокет, который у тебя использует функция WSAConnect, используется и для приема-отправки данных. Если это обмен по определенному алгоритму (слушается приветствие сервера, отправляется команда, принимаются данные, опять отправляется команда, принимаются данные, и так далее - то все делается просто. Если у клиента и сервера обмен асинхронный, тогда также используется select() или WSAWaitForMultipleEvents. Появились на сокете данные для чтения - считал, проанализировал, что-то ответил. Или сам что-то серверу отправил.
 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 20:05 16-01-2011 | Исправлено: vlary, 20:11 16-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Немного не на том акцентировал внимание... Как принять данные на сервере?
 
Я на сервере, в отдельном потоке, пробовал контролировать listen-сокет на событие FD_WRITE...  
 
При запуске сервера срабатывала WSAWaitForMultipleEvents с событием FD_WRITE и "заливала" экран консоли потоком бессмысленный данных.

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 21:05 16-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp Причем здесь listen-сокет? Весь обмен с клиентом осуществляется в потоке-обработчике. client_work чтением-записью в client_soc. Опять же в простейшем случае блокирующих сокетов  при запуске client_work в сокет пишется что нибудь типа 220 Ready,
и затем выполняется команда чтения. Получил от клиента какие-то данные, интерпретировал их как команду, выполнил, результат отправил в сокет, либо если это неправильная команда, отправил что-нибудь типа 500 Error.
Простейшим примером является эхо-сервер. Все, что он получает от клиента, сразу отправляет ему обратно. Можешь реализовать такой алгоритм, а для проверки просто зайти телнетом на порт своего сервера и что-то ему передать.


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 02:16 17-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Что-то я начинаю подозревать, что я установил баганую среду... Очень много финтов с кодом и не только:
 - после перезапуска может выдать до 30 "вниманий" при компайле, рекомпайл - и всё в порядке.
 - ни с того ни с сего появляется 1 ошибка... Пропадает только после рестарта компа.
 - меняю кпримеру WSASend на send, компайл, билд, меняю обратно как было, компайл, и получаю 2-5 ошибок... Лечится только ребутом компа.
 - создаю новый проект, аналогичный предыдущему по опциям, копипаст кода - до 15 ощибок на пустом месте. Сэйв, выход, запуск среды, лоад - всё в норме.
 - и таких прелестей море...
 
Я не отмахиваюсь, у меня пиратская среда... Вирей быть не может - антивирь "по доступу", файрволл "всё блокировать и уведомлять при попытке" + регулярные "рейды" антивируса по критическим местам.
 
Могла MS VC++ криво встать или чего-то нужно настроить?

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 07:35 17-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp
Цитата:
Могла MS VC++ криво встать или чего-то нужно настроить?
Может быть криво настроен проект, не подключены пути к хидерам, библиотекам. Ворнинги - дело нормальное, а ошибки нужно анализировать конкретно. Разработка программ - это не столько ремесло, сколько искусство, со всеми вытекающими отсюда последствиями.
 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 11:38 17-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Расслабил мозг пару дней и слёту нашёл недоработку...  
 
Вобщем суть кратка: перед использованием эвентов неплохобы их создавать... WSACreateEvent()...
 
Теперь всё отлично, сервер уверенно принимает входящие сообщения и успешно спамит на все активные, динамические сокеты.
 
Осталось исправить мелкие недоработки и консольный чат будет завершён. Ура, товарищи! )

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 07:12 21-01-2011
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp

Цитата:
 Ура, товарищи! )

лихо ты въехал, уважаю...
удачи!
 
---
 
vlary

Цитата:
Ворнинги - дело нормальное...

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

Цитата:
когда французская ракета Ариан грохнулась на взлёте из-за ошибки на Сях в вычислении эйлеровых углов (год 2001-2002)...

ребята поленились тайпкаст float-double сделать...

Всего записей: 25735 | Зарегистр. 06-12-2002 | Отправлено: 08:24 21-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp Молодец, таким и помочь приятно. А то у большинства просьба "помогите" означает исключительно "сделайте вместо меня". На халяву, ессно.


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 16:17 21-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Это пока ещё из головы не вышло одно из правил предыдущего форума: новый вопрос - новая тема. Неудачное, на мой взгляд, если дело косается программирования. Виноват, извиняюсь и делаю копипаст.
 
Вопросы:  
 - как я понял, функциям send(...) и recv(...) вообще "до фонаря" с чем работать, главное указать размер этого чего-то... Это так?  
 - именно из-за этого "до фонаря" можно переслать структуру, но с приёмом структуры придётся извратиться... Наверное это будет подобно пропусканию куска мяса через мясорубку с последующими попытками обратно собрать кусок мяса из фарша. Что тут можно придумать или уже всё придумано и опробовано?  
 - обмен структурами с полями фиксированных размеров стабильнее, чем обмен структурами с полями "случайных" размеров... Или всё равно и зависит от реализации?

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 10:03 26-01-2011 | Исправлено: Wc3Exp, 13:55 26-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp
Цитата:
как я понял, функциям send(...) и recv(...) вообще "до фонаря" с чем работать
В общем, да. Они работают с байтами. И это уже забота программиста - перевести экземпляр структуры или класса в последовательность байтов (чем, они физически, по сути дела, и являются), а затем на второй стороне из последовательности байтов собрать данный объект. Фиксированные там поля или нет - в данном случае все равно.
 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 11:09 26-01-2011
Wc3Exp

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
vlary
Если с передачей и приёмом я возможно разберусть, то с разгребанием данных по типам из этой кучи байт я наверное сяду в лужу.
 
Хотя если буду знать, что первые 8 байт - значение 1го поля стурктуры, следующие 10 байт - значение 2го поля структуры и т.д... то собрать структуру вполне смогу.
Но один серьёзный минус очевиден - придётся пересылать часть пустых полей, что плохо скажется на объёме сетевого траффика.
Но и плюс есть - быстрое разгребание пришедшей кучи байт.
 
А как поступить с полями разного размера только догадываюсь. Хотя если в "заголовке" всего этого байтового месива расставить смещения (от начала например) на различные значения, то вполне можно вывести значения полей структуры и не зависеть от размеров этих полей...
Подобную задачу я делал ранее, только не в С++ и не с байтами.
Как минус - более долгое разгребание пришедшей кучи байт при приёме и долгое формирование "заголовка" кучи при пересылке, как плюс - рациональное расходование сетевого трафика.
 
Я мыслю в правильном направлении или меня уже нетуда понесло?

Всего записей: 39 | Зарегистр. 01-01-2011 | Отправлено: 14:18 26-01-2011 | Исправлено: Wc3Exp, 14:24 26-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Wc3Exp
Цитата:
Я мыслю в правильном направлении или меня уже нетуда понесло?
В принципе - правильно. Смотри в сторону сериализации / десериализации  объектов. Чтобы не изобретать велосипед, глянь в сторону библиотеки ACE  
 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 15:42 26-01-2011
ClounViruS

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Wc3Exp Ну вот сразу же: в обработчике
 
Цитата:
 int client_index = (int)lpParam - 1;  
и в главном потоке
Цитата:
NewTreade[client_count] = CreateThread(NULL,0,client_work,(LPVOID)client_count,0,&TreadeId[client_count]);  
 
Ты не правильно параметры передаешь и читаешь.
В сервере должно быть (LPVOID) &client_count, а в клиентском потоке  (int)*lpParam
Иначе обработчик вместо индекса сокета нового клиента получит хрен знает что.  

 
Может я слепой, но я не пойму где тут ошибка ?
 
Добавлено:
Единственное ему client_count++ нужно было делать до создания потока, иначе поток может начать свою работу раньше, чем до client_count++ дойдет.

Всего записей: 4 | Зарегистр. 07-01-2010 | Отправлено: 20:50 31-01-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ClounViruS
Цитата:
Может я слепой, но я не пойму где тут ошибка
Вместо указателя передается значение, это разве не ошибка? Разница между &client_count и client_count понятна? Thread получает параметры по ссылке, а не по значению.

Цитата:
HANDLE WINAPI CreateThread(
  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in       SIZE_T dwStackSize,
  __in       LPTHREAD_START_ROUTINE lpStartAddress,
  __in_opt   LPVOID lpParameter,
  __in       DWORD dwCreationFlags,
  __out_opt  LPDWORD lpThreadId
);

 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 01:53 01-02-2011
ClounViruS

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Поток получает 4 байта, а что там будет хранить пользователь указатель или число это уже его право.

Всего записей: 4 | Зарегистр. 07-01-2010 | Отправлено: 03:36 01-02-2011
vlary



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ClounViruS
Цитата:
а что там будет хранить пользователь указатель или число это уже его право.
Возможно, в данном случае это и прокатит. А вот при передаче массива или структуры - уже нет. Поэтому лучше стараться следовать правилам в мелочах, дабы как-нибудь не обломаться по крупному.
 


----------
Заслуженный SCOтовод, почетный SUNтехник и любитель Кошек

Всего записей: 17290 | Зарегистр. 13-06-2007 | Отправлено: 18:52 01-02-2011
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Несколько вопросов по сетевому программированию на С++ (азы)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru