2015-05-24 2 views
3

Я читал о сокетах UDP в python., когда будет заблокирован блок socket.send()? (UDP)

По умолчанию сокет сконфигурирован так, чтобы отправлять или принимать блоки данных, останавливая выполнение программы до тех пор, пока сокет не будет готов. Вызовы для отправки() ожидают, что пространство буфера будет доступно для исходящих данных, а вызовы recv() ждут, когда другая программа отправит данные, которые можно прочитать.

Я понимаю принимающую часть, она должна ждать, пока другой конец не отправит. , но зачем нужен блок отправки? В книге говорится: «send() ожидает, когда будет доступно буферное пространство». Что такое буферное пространство?

Это для всей операционной системы или для каждого приложения.

Есть ли способ узнать, сколько буферного пространства доступно?

+0

Вы ищете полностью общий, переносимый ответ или практический ответ для определенной платформы? – abarnert

+1

Между тем, это действительно не вопрос Python; «Сокет» Python - это всего лишь тонкий слой над дескриптором файла (BSD) или дескриптором (WinSock) WSA, и, пометив эту специфику Python, вы ограничиваете число людей, которые будут видеть и отвечать на это. – abarnert

+0

@abarnert просто удалил тег python. – user3571278

ответ

1

Буфер, на который ссылаются сокеты BSD и документация POSIX, а также, по-видимому, на то, что вы читали, представляет собой буферизатор , а не для каждой системы или для каждого приложения. Это то же самое, что вы можете установить с помощью SO_SNDBUF. Когда этот буфер заполнен, send заблокирует.

Но вопрос в том, зачем этот буфер заполнить?

Под ядром, которое может видеть ваше приложение, ядро ​​обычно имеет нечто вроде кольца передающих буферов на сетевой адаптер. Когда сетевой адаптер завершает установку данных на буфере из проводника, он вытягивает еще один из кольца. Когда на кольце есть место, он вытягивает другой буфер передачи из одного из буферов сокета. Или, если слишком много буферов, ожидающих, оно отбрасывает некоторые из них, а затем тянет одно. Итак, эта часть - это общесистемная (или, по крайней мере, NIC-wide).

Итак, просто зная, что ваш размер буфера отправки действительно не говорит вам все, что вам действительно нужно, и чтобы по-настоящему понять это, вам нужно задавать вопросы, специфичные для вашего ядра. Если это Linux или * BSD, сетевой стек является открытым исходным кодом и довольно хорошо документирован (в Linux, если я правильно помню, и если мои знания в 2,4 раза по-прежнему полезны, поиск SO_SNDBUF и txqueuelen даст вам хорошие отправные точки); иначе это может быть не так. Конечно, Linux предоставляет всю информацию, которую можно найти где-то в файловой системе /proc, поэтому, узнав, что вы хотите найти, вы можете ее найти. * BSD не раскрывает столько же, но там много чего. Даже Windows имеет множество счетчиков производительности, которые имеют значение.

+0

buffer -> ring of buffers -> NIC-wire , поэтому буфер будет заполнен, если кольцо буферов будет заполнено, а кольцо буферов будет заполнено, если NIC никогда не закончил бы накладывать буферную ценность данных на провод i.ea socket будет заблокирован (в течение очень небольшого промежутка времени), если есть много других буферов, ожидающих, что их положит на провод , и он будет заблокирован навсегда, если возникнет проблема с сетевой адаптером (например, отключением от сети) Правильно ли я понимаю? – user3571278

+0

@ user3571278 Да, но помните, что часть буферов просто отбрасывается, если NIC отстает, поэтому отправления UDP никогда не должны блокироваться навсегда, они могут просто получить 100% потерю пакетов, даже не дойдя до сети. (По крайней мере, это один из способов, с помощью которого ядро ​​могло бы реализовать вещи ...) – abarnert

+1

Можете ли вы порекомендовать мне книгу, чтобы начать с того, чтобы узнать больше о том, как работают сокеты? – user3571278

Смежные вопросы