Подтвердить что ты не робот

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

У меня есть приложение клиент-сервер, где клиент находится на устройстве Windows Mobile 6, написанном на C++, а сервер на полной Windows и написан на С#.

Первоначально мне нужно было только отправить сообщения от клиента на сервер, а сервер только когда-либо отправлял обратно подтверждение, что он получил сообщение. Теперь я хотел бы обновить его, чтобы сервер мог отправлять клиенту сообщение для запроса данных. Поскольку в настоящее время он настроен таким образом, что клиент отправляет данные на сервер только в режиме приема, это не позволяет серверу отправлять запрос в любое время. Я должен был бы ждать данных клиента. Моей первой мыслью было бы создать еще один поток на клиенте с отдельным открытым сокетом, прослушивающим запросы к серверу... точно так же, как сервер уже имеет отношение к клиенту. Есть ли способ, в пределах одного потока и с использованием одного и того же сокета, всем серверам отправлять запросы в любое время?

Можете ли вы использовать что-то для эффекта WaitForMultipleObjects() и передать ему буфер приема и событие, которое сообщает, что есть данные для отправки?

4b9b3361

Ответ 1

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

в это время сервер мог отправлять сообщения обратно клиенту через одно и то же открытое соединение.

Кроме того, но я не знаю, применимо ли это для вас, у меня было какое-то сердцебиение клиентов, отправленных на сервер, давая понять, что он все еще в сети. Таким образом, сервер знает, когда клиент был принудительно отключен от сети, и он мог отметить этого клиента как автономный.

Ответ 2

Использование асинхронной связи полностью возможно в одном потоке!

Существует общий шаблон проектирования в разработке сетевого программного обеспечения, называемый шаблоном реактора (посмотреть на эту книгу). Некоторая известная сетевая библиотека обеспечивает реализацию этого шаблона (посмотреть ACE).

Вкратце, реактор - это объект, вы регистрируете все свои гнезда внутри, и вы чего-то ждете. Если что-то произошло (появятся новые данные, соединение закрывается...), реактор уведомит вас. И, конечно же, вы можете использовать только один сокет для отправки и получения данных асинхронно.

Ответ 3

Я не понимаю, хотите ли вы добавить асинхронные биты к серверу на С# или на клиенте на С++.

Если вы говорите об этом на С++, настольные платформы Windows могут выполнять асинхронные операции ввода-вывода сокета через API, которые используют перекрывающиеся ввода-вывода. Для сокетов WSASend WSARecv позволяют использовать async-I/O (читайте документацию по их параметрам LPOVERLAPPED, которые вы можете заполнить событиями, которые устанавливаются при завершении ввода-вывода).

Я не знаю, поддерживают ли платформы Windows Mobile эти функции, поэтому вам, возможно, придется сделать дополнительные копания.

Ответ 4

Проверьте asio. Это перекрестная совместимая библиотека С++ для асинхронного ввода-вывода. Я не уверен, что это было бы полезно для сервера (я никогда не пытался связать стандартную DLL С++ с проектом С#), но для клиента это было бы полезно.

Мы используем его с нашим приложением и решаем большинство наших проблем с IO concurrency.