В чем разница между read () и recv () и между send () и write ()?

140

В чем разница между read() и recv(), а также между send() и write() в программировании сокетов? производительность и скорость и другое поведение.

  • 3
    #define write(...) send(##__VA_ARGS__, 0) что запись реализована следующим образом: #define write(...) send(##__VA_ARGS__, 0) .
Теги:
sockets
network-programming
posix

6 ответов

84
Лучший ответ

Единственное различие заключается в том, что recv/send позволяет указать определенные параметры для фактической операции. чтение/запись - это универсальные функции дескриптора файла, в то время как recv/send немного более специализированы (например, вы можете установить флаг для игнорирования SIGPIPE или для отправки сообщений вне диапазона...).

  • 2
    Это неверно, есть еще одно отличие в случае дейтаграмм 0 длины - если дейтаграмма нулевой длины находится в состоянии ожидания, read (2) и recv () с аргументом flags, равным нулю, обеспечивают другое поведение. В этом случае read (2) не имеет никакого эффекта (дейтаграмма остается ожидающей), тогда как recv () использует ожидающую дейтаграмму.
  • 2
    @AbhinavGauniyal Как это обеспечит другое поведение ? При наличии 0-байтовой дейтаграммы и recv и read не доставят вызывающей стороне никаких данных, но также не сообщат об ошибке. Для звонящего поведение такое же. Вызывающий может даже не знать ничего о дейтаграммах (он может не знать, что это сокет, а не файл, он может не знать, что это сокет дейтаграммы, а не сокет потока). То, что датаграмма остается в ожидании, является неявным знанием того, как стеки IP работают в ядрах и невидимы для вызывающей стороны. С точки зрения вызывающих, они все равно будут обеспечивать равное поведение.
Показать ещё 6 комментариев
68

Пер первый хит в Google

read() эквивалентно recv() с параметром flags из 0. Другие значения параметра flags изменяют поведение recv(). Аналогично, write() эквивалентен send() с флагами == 0.

  • 26
    Это не вся история. recv можно использовать только в сокете, и он выдаст ошибку, если вы попытаетесь использовать его, скажем, в STDIN_FILENO .
  • 63
    Эта тема стала первым хитом в Google, Google любит stackoverflow
7

read() и write() являются более универсальными, они работают с любым файловым дескриптором. Однако они не будут работать в Windows.

Вы можете передать дополнительные параметры send() и recv(), поэтому вам, возможно, придется использовать их в некоторых случаях.

6

Недавно я заметил, что когда я использовал write() в сокете в Windows, он почти работает (FD, переданный в write(), не совпадает с переданным в send(); я использовал _open_osfhandle() чтобы передать FD на write()). Однако это не сработало, когда я попытался отправить двоичные данные, содержащие символ 10. write() где-то вставленный символ 13 до этого. Изменив его на send() с параметром flags из 0, эта проблема была исправлена. read() может иметь обратную проблему, если 13-10 являются последовательными в двоичных данных, но я их не тестировал. Но это, по-видимому, еще одна возможная разница между send() и write().

3

Другое дело в Linux:

send не позволяет работать с не-socket fd. Таким образом, например, для записи на порт usb требуется write.

3

"Производительность и скорость"? Разве это не... синонимы здесь?

Во всяком случае, вызов recv() принимает флаги, которые read() не делает, что делает его более мощным или, по крайней мере, более удобным. Это одно отличие. Я не думаю, что существует значительная разница в производительности, но не проверена.

  • 15
    Возможно, отсутствие необходимости иметь дело с флагами может быть воспринято как более удобное.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню