|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
Поток в настоящее время используется предыдущей версией потока27.10.2024, 00:31. Показов 4772. Ответов 64
Метки нет (Все метки)
Здравствуйте, уважаемые программисты! Писал клиент и сервер. Идея такова, что выбирается listView элемент, затем нажимается кнопка Button1 и сервер отправляет на клиента команду, клиент принимает ее и в ответ шлет сначала эту же команду, затем число строк из своего listView, а затем в цикле пересылаются все строки. Так вот, при первом нажатии срабатывает нормально, результат можно видеть на картинке, а при втором нажатии вылезает ошибка из названия темы. Помогите, кто может, как избавиться от этой ошибки? В архиве прикрепляю проекты Visual Studio клиента и сервера.
0
|
|
| 27.10.2024, 00:31 | |
|
Ответы с готовыми решениями:
64
В некоторых странах Дальнего Востока (Китае, Японии и др.) использовался (и неофициально используется в настоящее время) В некоторых странах Дальнего Востока (Китае, Японии и др.) использовался (и неофициально используется в настоящее время) Какие на ваш взгляд ОС Windows являются провальными по сравнению с предыдущей версией и почему? |
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 05.11.2024, 04:26 [ТС] | |
|
wizard41, Ну вот, визуально повторил ваше приложение. И изучать материал не пришлось. А как оно там работает внутри это уже другой разговор
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 05.11.2024, 04:30 [ТС] | |
|
P.S. Повторил не только визуально, но и функционально. Но как...
0
|
|
|
|
|||||||
| 05.11.2024, 13:10 | |||||||
|
Даже запустил клиент и сервер - не понятно что и когда нажимать, вылетело два исключения, сервер закрылся по ошибке. Больше экспериментировать не стал. О явных недоработках и ошибках в коде: - все опять свалено в кучу, в классе формы. - метод получения директории exe-файла, это что-то с чем-то: GetExeDirectory
- недостижимый код в методах. - названия кнопок button1, button2... ни о чем не говорят. Играй в угадайку что надо нажать и для чего. - событие button1_Click что-то отправляет клиенту без всяких проверок: а запущен ли сервер и подключен ли хоть кто-то к нему? На этом, скорее всего, вывалилось приложение у меня, когда я нажал на button1.- то же, с событием button2_Click, если сервак не запущен, приложение упадет с исключением NullObjectReference.- класс ServerObject:- создаются новые клиенты при отправке им сообщений. Те клиенты, что подключились и опознаны сервером AcceptTcpClientAsync(), просто висят в вакууме и никому не нужны.- нет возможности отменить прослушку - задачи запускаются и улетают в бесконечность, работая сами по себе. - нет возможности остановить сервер и запустить новый, с другими параметрами (ip, port...). - класс ClientObject:- ссылки на ServerObject server, о котором клиенты и знать ничего не обязаны. Клиенты работают с удаленным подключением, получив из него поток; что же из себя представляется сервер и тем более явно ссылаться на него - им ни к чему.- клиенты получают стримы "просто так", без всяких подключений и проверок что хоть кто-то есть по указанному адресу. - ничего не Dispose-иться и не удаляется; срем в память чем только можем. - метод приема почему-то считает, что пришедшие сообщения гарантированно должны начинаться с некоторых символов: нет даже базового представления о протоколе TCP. ... на этом наверное достаточно. В общем, код похож на невесть от куда выдранные куски, с попытками их хоть как-то связать между собой.
0
|
|||||||
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 05.11.2024, 21:24 [ТС] | |
|
wizard41, Простите, я не то скинул, вот то, что хотел скинуть. Два экзешника, копирующие два ваших экзешника
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 05.11.2024, 21:29 [ТС] | |
|
Мы отклонились от темы. Наверно стоит пояснить, что я согласен со всеми, кто написал, что мне нужно изучить тему подробнее. А экзешники я скинул, чтобы показать, что можно скопировать чужое приложение, но что там будет под капотом неизвестно. Так же как вы скинули свои экзешники, чтобы продемонстрировать их работу.
0
|
|
|
|
|
| 06.11.2024, 01:04 | |
|
Оаг, Окей.
Какой конечный смысл этой задачи? Сделать, чтобы работало или в учебных целях? Вот так написал его я, на скорую руку: wizard41.TcpServerClient.Demo.7z Изучай..
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 06.11.2024, 19:07 [ТС] | |
|
wizard41, Ну, идея заключается в том, что есть несколько клиентов и есть сервер. Они взаимодействуют так: сервер подключается к клиенту, посылает команду, клиент принимает ее, в зависимости от команды, отсылает отчёт (какую-то информацию) и дальше они разрывают соединение. При этом, перед началом работы надо как-то сконфигурировать клиенты, чтобы принимали подключение только от сервера. А сервер должен настроить список клиентов, которым будет отправлять команды. Как-то так.
Добавлено через 38 секунд Спасибо за пример. Буду изучать
0
|
|
|
|
|
| 06.11.2024, 19:12 | |
|
Оаг, понял. Сервер не должен ни к кому подключаться. Он просто "завелся" и ждет, пока к нему кто-то присосется.
Если увидел клиента, то можно начинать с ним обмен... В моем примере так и сделано - сервер посылает команду клиенту (getdata), а тот отвечает...
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 06.11.2024, 19:21 [ТС] | |
|
wizard41, А если у меня сервер занимается централизованным управлением клиентами, то мне надо, чтобы именно сервер запрашивал подключение у клиентов. Или как по другому? Держать соединения со всеми клиентами всегда открытым? Сервер то может в любое время запросить отчёт у клиента, а как он запросит отчёт, если вы говорите, что клиент должен сначала запросить соединение?
0
|
|
|
|
|
| 06.11.2024, 19:28 | |
|
Оаг, сервер не может ничего запрашивать у клиентов, которых нет. Он работает только с реально подключенными абонентами.
Клиент соединяется с сервером, тот теперь "знает" что есть такой-то клиент... Ну и работает с ним.
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 06.11.2024, 19:34 [ТС] | |
|
wizard41, Ну, то есть, если у меня будет 100 клиентов в локальной сети, то мне надо, чтобы соединение с каждым из них было постоянно открыто, чтобы сервер мог в любой момент любому клиенту отправить команду и получить ответ в виде информации?
0
|
|
|
|
|
| 06.11.2024, 19:45 | |
|
Оаг, я думаю, что не надо разрывать соединение с клиентами. Клиент либо жив, либо кот...
Пока клиент есть, с ним сервер работает. Странно делегировать серверу обязанности искать клиентов самому... Добавлено через 4 минуты Оаг, это можно в том случае, если сервер заранее "знает" своих клиентов, по ip-адресам, например. Но все равно, зачем ему лишняя нагрузка - отправлять сообщения тому, кого нет. Он должен работать по факту, т.е. с теми, кто к нему подключен в данный момент. Добавлено через 2 минуты Само же наличие клиента, который был подключен ранее, определится со следующей посылкой к нему команды. TCP протокол может определить, доставлено сообщение или нет. Если не доставлено, то клиент отвалился...
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
||||||
| 06.11.2024, 20:23 [ТС] | ||||||
|
wizard41, Хорошо, тогда другой вопрос. А как мне при получении сообщения сервером, понять, от кого оно пришло? Например, я отправил команду на три клиента, ответ может прийти в разном порядке. Как мне написать код, который определяет, от кого пришло сообщение? Вот до этого у меня был код
То есть у каждого клиента был собственный Reader. Но при большом количестве клиентов это все сильно нагружало процессор. А как вы предлагаете, мне сначала надо принять подключения от всех клиентов. А потом как-то принимать в коде все сообщения и определять, кому принадлежит сообщение. А до этого не приходилось определять, потому что у каждого клиента был свой Reader и сообщения принимались отдельно для каждого клиента. Так вот как с помощью кода принимать все сообщения и определять, от какого клиента сообщение? Добавлено через 5 минут Если что, изначальный код сервера и клиента брался с сайта metanit.com "консольный tcp-чат". Возможно, он просто не подходит под мои задачи
0
|
||||||
|
|
|
| 06.11.2024, 20:34 | |
|
у каждого клиента есть его
EndPoint, который четко определяет кто источник сообщения.В целом, направление верное: сервер постоянно ждет подключений и принимает их (в отд. потоке). Все подключенные клиенты работают в своих потоках. Сервак рассылает команды тем, кто есть в списке активных клиентов. Если кто-то не получил команду, то выбывает из этого списка... Добавлено через 1 минуту можно даже в сам протокол сообщений вкладывать "имя" клиента... Тут вариантов тьма, на что фантазии хватит..
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 06.11.2024, 20:58 [ТС] | |
|
wizard41, Окей, спасибо за советы. Буду изучать и пытаться что-то сделать
0
|
|
| 06.11.2024, 23:56 | |
|
Заранее извиняюсь если сказанное не будет иметь отношения к задаче ТСа.
wizard41, не стоит упрямо выворачивать любую задачу под стандартные решения. Это я про то, что сервер всегда тупо слушает. Возможны крайне редкие нестандартные решения, которые имеют место быть. Рассмотрим такой пример: есть сервер, который обязан собирать инфу с распределённых объектов, пусть это будут эл.подстанции (далее ЭП). Когда какая-то ЭП подключается в систему, то она обязана зарегистрироваться на сервере, т.е. предоставить все свои данные и IP-адрес тоже, правда он должен быть статическим. В случае изменения контактной информации её актуализация на сервере также ложится на клиента (ЭП). На протяжении любого промежутка времени ЭП молчат, но собирают или не собирают какие-то данные. Внезапно, очнувшемуся в 3 часа 47 минут ото сна, диспетчеру вздумалось узнать какой-то показатель с ЭП №ХЗ, он жмёть кнопочку и... Что называется продолжите фразу. Всё просто, именно сервер будет стучаться в сторону ЭП и запрашивать у неё данные. Стандартный подход тут не эффективен, так как в этом случае ЭП (клиенты) должны периодически стучаться на сервер, сообщать ему "я жив" и всё в этом духе. Но зачем? Пример конечно оторван от действительности потому, что в реалиях мониторящиеся объекты почти всегда на связи и именно они натравливаются на сервер, а не наоборот. Но что если нам такое не нужно, а нужно как написано выше.
0
|
|
|
|
|
| 07.11.2024, 00:44 | |
|
Uswer, не спорю. Описанное тобой - это стандартная реализация Мастер-подчиненный, где мастер задает тон.
Но я про этот вариант и сам сказал ранее. Если у ТСа сервер знает всех своих клиентов, то можно сделать и так. Но нужно иметь в виду, что будет затрата времени на выяснение - кто на связи..
0
|
|
|
0 / 0 / 0
Регистрация: 28.02.2020
Сообщений: 103
|
|
| 07.11.2024, 02:04 [ТС] | |
|
wizard41, так если это настраивать в локальной сети, то можно сконфигурировать сервер, чтобы имел список ip-адресов, к которым надо обращаться. И не думаю, что затрата времени для одного клиента будет такой уж большой, если нам не нужно получать ответ моментально. А вот если отослать команду сразу всем клиентам, то сначала придется действительно устанавливать со всеми ними соединение.
0
|
|
|
|
|
| 07.11.2024, 13:26 | |
|
Оаг, ну.. не знаю, по мне так вариант где сервер всех знает и опрашивает - в данном случае просто лишний. У него будет лишняя работа.
Сервер и так узнает клиента(ов), когда они подключатся. А когда кто-то не подключен, то он не подключен, и смысл его опрашивать какой? Допустим пример с зарплатой на карту: можно в день зарплаты каждые 5 минут заходить в онлайн-банк и проверять, пришли ли деньги. Но это лишняя работа: когда деньги поступят на счет - мы и так узнаем (придет SMS, Push...). Так и здесь. Но выбор за тобой, делай как нравится..
0
|
|
|
|
|||
| 08.11.2024, 11:32 | |||
|
Тут лютая ошибка: при закрытии соединения ReadLine возращает null и получаете вечный цикл, который отлично забьет вам ядро CPU под 100%. Несколько переподключений, и лежать будет весь сервер. Вообще возьмите за правило что while(true) аналогично goto: лучше избегать по возможности. А дальше уже можно по разному реализовывать взаимодействие с клиентами: через агрегатор, команды, ивенты или ту же MQ. Я обычно практикую подход через Handlers: - на каждый тип сообщения создается обработчик - набор таких обработчиков агрегируется и передается сессии - входящее сообщение скармливается агрегатору, он ищет нужный обработчик и вызывает его Если нужно просто кому-то, что-то отравить без ожидания входящего сообщения, то тут вообще элементарно: фоновый сервис просто должен иметь доступ к списку сессий.
0
|
|||
| 08.11.2024, 11:32 | |
|
Описать два потока: первый поток записывает данные в буферную память, а второй поток – считывает Нужны ли эти теги в настоящее время Захват воспроизведения. Недоступно в настоящее время Вчера составила $ 15,12, в настоящее время составляет $ 14,82?
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет.
Но обычно это 50 лет и более.
Наверное, закисление почвы происходит сезонно в средней. . .
|
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
|
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS
Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
|
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи.
Через несколько переработок от PHP кода к C89 (надеюсь, 89).
Но довольно запутанно получилось. Код для Linux.
Но если убрать time и то, что с ним. . .
|
|
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки
Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
|
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы
Всем привет! Хочу поделиться свежим (и довольно. . .
|
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
|
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения:
- добавлена многоязычность
- добавлено снятие скриншотов
- добавлено поддержание бафов хождения по воде (для жреца, дк и шамана)
- и так, по. . .
|