У меня есть программа на С ++, работающая под Linux Debian 9. Я делаю простое чтение () из файлового дескриптора:
int bytes_read = read(fd, buffer, buffer_size);
Представьте, что я хочу прочитать еще несколько данных из сокета, но я хочу пропустить известное число байтов, прежде чем перейти к интересующему меня контенту:
int unwanted_bytes_read = read(fd, unwanted_buffer, bytes_to_skip);
int useful_bytes = read(fd, buffer, buffer_size);
В Linux существует ли общесистемное «встроенное» расположение, в которое я могу записать ненужные байты, вместо того, чтобы поддерживать буфер для нежелательных данных (как unwanted_buffer
в приведенном выше примере)?
Я предполагаю, что то, что я ищу, будет (вроде) противоположностью MSG_PEEK
в мире сокетов, то есть ядро очистит bytes_to_skip
от своего буфера приема перед следующим полезным вызовом recv.
Если бы я читал из файла, то lseek
было бы достаточно. Но это невозможно, если вы читаете из сокета и используете ввод / вывод scatter / collect и хотите удалить одно из полей.
Я думаю о чем-то вроде этого:
// send side
int a = 1;
int b = 2;
int c = 3;
struct iovec iov[3];
ssize_t nwritten;
iov[0].iov_base = &a;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = &b;
iov[1].iov_len = sizeof(int);
iov[2].iov_base = &c;
iov[2].iov_len = sizeof(int);
nwritten = writev(fd, iov, 3);
// receive side
int a = -1;
int c = -1;
struct iovec iov[3]; // you know that you'll be receiving three fields and what their sizes are, but you don't care about the second.
ssize_t nread;
iov[0].iov_base = &a;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = ??? <---- what to put here?
iov[1].iov_len = sizeof(int);
iov[2].iov_base = &c;
iov[2].iov_len = sizeof(int);
nread = readv(fd, iov, 3);
Я знаю, что я мог бы просто создать другую переменную b
на принимающей стороне, но если я не хочу, как я могу прочитать байты sizeof(int)
, которые она занимает в файле но просто сбросьте данные и перейдите к c
? Я мог бы просто создать общий буфер для дампа b
, все, что я спрашивал, это если такое расположение по умолчанию.
[EDIT]
Следуя совету @inetknght, я попытался сопоставить память / dev / null и выполнить сбор в сопоставленный адрес:
int nullfd = open("/dev/null", O_WRONLY);
void* blackhole = mmap(NULL, iov[1].iov_len, PROT_WRITE, MAP_SHARED, nullfd, 0);
iov[1].iov_base = blackhole;
nread = readv(fd, iov, 3);
Однако blackhole
отображается как 0xffff
, и я получаю сообщение об ошибке 13 «Отказано в доступе». Я попытался запустить свой код как su, и это тоже не работает. Возможно, я неправильно настраиваю mmap
?