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

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

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

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


person Adam Haile    schedule 04.08.2008    source источник


Ответы (4)


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

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

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

person sven    schedule 04.08.2008

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

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

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

person Steve Gury    schedule 17.08.2008

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

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

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

person fastcall    schedule 05.08.2008

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

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

person roo    schedule 11.08.2008