Я реализую Формат провода ZeroMQ над Win32 именованные каналы. Формат требует добавления сообщения с его размером. Мой интерфейс выглядит send(std::vector<unsigned char>)
поэтому пользователь уже выделил буферу точный размер своих данных, и я строю заголовок размера на основе vector.size()
,
В настоящее время я отправляю заголовок размера в отдельной записи в канал. Но затем, если последующая запись фактического содержимого сообщения не удалась, поток данных остается в плохом состоянии, когда получатель ожидает больше данных, но отправитель считает, что сообщение не удалось.
Я хотел бы объединить заголовок размера и содержимое в одну запись канала, чтобы заголовок не проходил сам по себе. Но я бы хотел избежать копирования vector
содержание, потому что оно может быть довольно большим. Есть ли способ объединить два буфера в одну запись Win32 трубы?
Если нет, я всегда могу добавить что-то вроде unsigned char *getPipeBuffer(size_t size)
это выделяет дополнительное пространство для заголовка. Но было бы неплохо оставить интерфейс без изменений.
Рассматривали ли вы использовать трубу с PIPE_READMODE_MESSAGE
? Таким образом, вы получаете размер сообщения бесплатно и вам не нужно включать его в само сообщение.
При записи операция записи заканчивается только тогда, когда написано все сообщение.
При чтении операция чтения читает одно сообщение. Или, если сообщение не помещается в буфер канала, читает его часть, то сообщает, что ожидается больше данных, и что вам нужно вызвать его снова, чтобы получить остальную часть сообщения.
Нет необходимости передавать размер сообщения, потому что получатель всегда знает, когда он закончил читать одно сообщение.
Обратите внимание, что для клиентов канала необходимо изменить режим чтения канала с помощью вызова SetNamedPipeHandleState
,
Больше информации Вот.
Мой первый ответ был бы использовать WriteFileGather но это сопровождается строгими требованиями к выравниванию буферов, которые вы передаете в функцию, что может быть трудно реализовать, и после проверки документации кажется, что это может вообще не работать с каналами, хотя я не понимаю, почему «т.
Я думаю, что делать две разные записи, одну для размера и одну для данных, должно быть хорошо. Вы спрашиваете, что произойдет, если вторая запись завершится неудачно, и поток останется в каком-то несовместимом состоянии, где другой конец ожидает больше данных. Но даже один запрос на запись может оставить канал в таком состоянии: WriteFile может, например, записать меньше байтов, чем запрошено, что потребует второй записи, и эта вторая запись может завершиться ошибкой.
Обратите внимание, что страница, которую вы используете в качестве ссылки, в начале говорит: «ПРЕДУПРЕЖДЕНИЕ. Этот текст устарел и относится к старой версии ØMQ. Он остается здесь для исторического интереса. НЕ ИСПОЛЬЗУЙТЕ ЭТО, ЧТОБЫ УЗНАТЬ ØMQ».
Это не формат провода 0MQ. Если вам нужен проводной формат 0MQ, он находится на сайте RFC по адресу http://rfc.zeromq.org/spec:15.