Чтение из сокета по смещению с флагом MSG_PEEK?

Я хочу уйти от последовательного и медленного чтения из сокета, в котором мы используем:

struct PACKET_STRUCT{
   int PacketType;
   char buffer[50];
};

char buffer[sizeof(PACKET_STRUCT)];
struct sockaddr_storage addr;
socklen_t fromlen = sizeof(addr);
int iByteCount = recvfrom(CProperties->m_iSocket, buffer, sizeof (buffer), MSG_PEEK, (struct sockaddr*)&addr, &fromlen);

Это означает, что если клиент отправляет мне PACKET_STRUCT (пакет №1) и еще один PACKET_STRUCT (пакет №2) — мне придется прочитать пакет №1, прежде чем я смогу прочитать пакет №2.

Есть ли способ, с помощью которого я могу выполнить смещение в recvfrom, начиная с sizeof(PACKET_STRUCT), чтобы я мог читать пакет №2, не читая пакет №1?

И так далее sizeof(PACKET_STRUCT)*2 для чтения пакета #3.

Я понимаю, что существует pread(), который позволяет читать дескриптор файла с определенным смещением, но я хотел бы сохранить флаг MSG_PEEK.

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

Итак, мой вопрос: существует ли recvmsg-подобная функция со смещением и флагами MSG_PEEK?


person Lucky    schedule 21.11.2013    source источник


Ответы (1)


Нет концепции поиска или пропуска данных в сокете, поэтому вы не можете этого сделать. (lseek/pread нельзя использовать в сокетах)

Однако некоторые платформы позволяют получать много дейтаграмм за один вызов, используя recvmmsg. , если вас не волнует первое сообщение - просто получите и проигнорируйте его.

person nos    schedule 21.11.2013
comment
Действительно здорово! Поскольку неблокирующая функция recvmmsg() возвращается немедленно, но также возвращает количество отправленных сообщений. Тогда я смогу заставить рабочих майнить через эту структуру mmsghdr. - person Lucky; 22.11.2013
comment
Но поскольку recvmmsg() является расширением recvmsg(). Разве это не то же самое, что использовать recvmsg(), а затем отправить работника для работы с этим буфером? Или есть больше преимуществ в скорости от использования recvmmsg() в зависимости от того, как мы его оптимизируем? - person Lucky; 22.11.2013
comment
@ К счастью, поскольку вы можете прочитать много сообщений за один системный вызов, вы можете избежать большого количества системных вызовов, что может быть огромной победой. И если вы затем структурируете своих воркеров так, чтобы вы могли передавать им много пакетов за раз, что может быть проще при использовании recvmmsg(), вы тоже выиграете от этого (поскольку сообщения буферизуются и заставляют воркеры обрабатывать несколько из них за один раз). создает меньше накладных расходов). Предполагается, что вы используете UDP. Для TCP вы каждый раз читаете большой буфер, анализируете все полные сообщения, которые вы прочитали, и обрабатываете их - не пытайтесь читать одно маленькое сообщение за раз. - person nos; 22.11.2013