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

StackOverflow https://stackoverflow.com/questions/1241

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

Мне неясно, хотите ли вы добавить асинхронные биты на сервер на C# или на клиент на C++.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top