Здравствуйте, Jolly Roger, Вы писали:
JR>Ну и в чём трудность? Получили пакет, обработали. Если требуется ответ, отправляете его вызовом WsaSend, иначе вызываете WsaRecv
Т.е. могу сразу после вызова WSASend вызывать WSARecv , не дожидаяь при этом уведомления о завершении WSASend?
JR>Тоже нет. Но вот с одновременным вызовом нескольких WsaSend или WsaRecv не столь однозначно, и дело даже не в потокобезопасности самих функций, с этим в асинхронном режиме всё в порядке. Трудности в логике обработки уведомлений о завершении. Например, если у Вас будет несколько активных запросов на чтение из одного сокета, то может статься, что уведомление о получении разных частей одного пакета Вы получите в разных потоках, и сборка такого пакета в единое целое может оказаться делом нетривиальным. И зачем оно? С несколькими WsaSend тоже есть проблема. Допустим, у Вас 10 потоков одновременно вызывают WsaSend. Достаточно высока вероятность, что несколько из них завершатся с ошибкой WSAEWOULDBLOCK, и для разруливания такой ситуации Вам всё равно придётся организовать ассоциированную с сокетом очередь отправки. На мой взгляд проще и надёжней сразу организовать такую очередь из структур WSABUF, и при получении уведомления о завершении WsaSend проверять её.
Понятно. А если я текущий HTTP сервер переделаю так:
1) В потоке WorkThread буду читать данные через WSARecv и если требуется "срочный" ответ клиенту, то тут же вызываю WSASend (сейчаз в блокируемом сервере так и зделано).
2) Так же имеются "срочные" данные от самого сервера, которые будут тоже отправляться вызовом WSASend (это в отдельном потоке или потоках).
Как раз в этой схеме и возможна ситуация с перекрытым вызовом WSASend. Значит, как вы предлагаете, надо организовать очередь для WSASend.
Т.е. средует для каждого клиента выделить отдельный буфер для WSASend. А как правильно тогда обслуживать такой буфер, стремясь как можно быстре его "очистить"?
Здравствуйте, netch80, Вы писали:
D>>Т.е. эта реализация обеспечивает протокол обмена типа: acceptEx -> получили запрос -> отправили ответ -> ждём запрос...
D>>У меня же протокол совсем не HTTP. У меня клиент может послать пакет серверу и при этом сервер не обязан на него отвечать. Да и сервер посылает клиенту команды, которые не требуют подтверждения.
N>Ну это принципиально ничего не меняет. Если сервер не должен отвечать, он может просто закрыть соединение и забыть. С другой стороны, в таком случае непонятен смысл самого этого протокола. Чтобы так работать, или данные должны быть несущественны вообще, или достаточно часто повторяться, чтобы одиночные проблемы не приводили к существенной потере.
Согласен частично. Просто тут коннект с клиентом постоянен на протяжении всей работы клиента. И когда я делал клиента на блокируемых сокетах мне совсем не хотелось делать ожидание ответов от сервера о приёме данных (что бы не тормозить работу).
Поступление важных данных проверятся сервером через спец. механизм. Поэтому если сервер поймёт что ему что то не пришло, то следует дисконнект.
D>>Вот и не знаю как этот HTTP сервер передалать под мой протокол.
N>В чём ещё разница в протоколах? Может ли, например, сервер присылать асинхронные оповещения? Насколько я понял по описанию — да, но тогда прошу изложить подробнее.
Если под асинхронными сообщениями понимаются данные, независящие от "запросов" клиента, то тогда может.
D>>Да и не знаю как в этом сервере из любого другого потока в любой момент времени послать "моментально" данные клиенту.
D>>Да и можно ли использовать один и тот же сокет в разных потоках "одовременно"?
N>Лучше не надо. Или использовать блокировки мьютексами, критическими секциями, etc. для доставки, или делать то же самое для привязанного к сокету буфера, а собственно отправку по возможности — возложить на одну нить (уже не столь важно, какую).
Выше эту идею обмозговал чуточку ...
D>>Может стоит посмотреть в сторону перекрытого ввод-вывода, реализованого через Event'ы ?
N>А в чём принципиальная разница? (не пишу под Windows)
Да вот тоже думаю что нет особой разницы.