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

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

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

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

4 ответа

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

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

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

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

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

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

  3. Проверить asio . Это перекрестная compatable библиотека c++ для asyncronous IO. Я не уверен, будет ли это полезно для сервера ( я никогда не пытался связать стандартную DLL c++ с проектом c#), но для клиента это было бы полезно.

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

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

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

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