2015-04-19 6 views
0

Предположим, у меня есть этот Python код:Когда ОС скрывает розетку?

read=true; 
i=0; 
while (read){ 
    data =sock.recv(100); 
    i+=1; 
    print data; 
} 

Теперь на другом конце я кормить гнездо с 101 символа. В конце получения значение i будет равно 2, потому что весь фид не будет в буфере 100 символов - один оставшийся символ перейдет на другую итерацию. Это понятно: заполнение буфера, информация сбрасывается на переменную data. Но что произойдет, если я буду кормить сокет только 10 символами? Буфер не заполняется, так как на Земле это sock знает, что после получения 10 символов больше не будет потока, и пришло время сбросить буфер и вернуть сообщение в «данные»?

Фактический пример копипаст:

SERVER:

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
s.bind("/tmp/somesfile") 
s.accept(1) 
s.listen() 
conn, addr = s.accept() 

i=0 
read=True 

while read: 
    conn.recv(10) 
    i = i + 1 
    print i 

КЛИЕНТ:

c = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
c.connect("/tmp/somesfile") 

ПЕРЕДАЧА ДАННЫХ (консоль на КЛИЕНТА)

>>> c.send("aaaaa") 
5 
>>> c.send("a") 
1 
>>> c.send("a") 
1 
>>> c.send("a") 
1 
>>> c.send("a") 
1 
>>> 

ПОЛУЧЕНИЕ ДАННЫХ (консоль на сервере SERVER)

'aaaaa' 
1 
'a' 
2 
'a' 
3 
'a' 
4 
'a' 
5 

Сервер имеет 10-байтовый буфер, подготовленный для принятых данных. При первом всплеске он получил 5 символов - все 5 были сохранены в том же буфере и сброшены. На следующих 4 серверах всплесков было отправлено 4 шара один за другим с интервалом времени между приемами. Все эти символы были сброшены в один и тот же шаблон, то есть один за другим. Ни в одном из случаев буфер, заполненный. Мой вопрос: что заставляет серверный сокет сбросить буфер отдельно от переполнения? Как теперь, когда другой байт не появится?

Строки представляют собой шаблоны байтов с нулевым завершением. Сокеты-потоки что-то прекращаются?

+0

Я не уверен, что вы просите. Способ 'recv' работает, вы получаете все, что находится в буфере, до суммы, которую вы запрашиваете (это означает: возможно, меньше, чем вы просите). Поэтому, если их всего 10 байт, вы получаете 10 байт. В чем особая проблема, с которой приходится сталкиваться ОС? – Damon

+0

, и если вы запрашиваете 10 байт и их всего 5? будет ли он блокировать поток процесса, пока кто-то не подаст его еще 5 байтами и не заполнит буфер? Я мог бы быть испорчен python .. там все упрощено .... – netikras

+0

Я не помню, как он находится на C, но на Python, если я recv (100), и загружаю сокет на другой конец с 100 байтами по одному -one (скажем, с 1-секундной задержкой между каналами), процесс разблокируется 100 раз. Если я подаю его на 100 байт сразу - recv() разблокирует только один раз.Это означает, что recv() освобождает блок, даже если буфер не заполнен. В основном я отправляю одни и те же данные только в разных частях, а поведение процесса отличается от – netikras

ответ

1

В конце приема значение I будет 2

Нет. Это может быть что-нибудь от 2 до 101. recv считывает по меньшей мере, один байт и максимум столько же, сколько было отправлено с удаленной стороны. Он может читать любую сумму между ними.

так, как на Земле делает это носку знать, что после того, как будут получены 10 символов не будет больше потока, поступающего

Это не делает. Это дает вам то, что есть.

+0

Я изменил свой вопрос на примере того, что мне пригодится .. Как это может быть что угодно [2; 101]? Почему> 2, если я отправляю данные с одним потоком? Я знаю, что recv() читает хотя бы один байт, но почему он не возвращает байты один за другим и достаточно интеллектуальный, чтобы знать, когда поток закончился, и вернуть все, что находится в буфере, хотя оно не заполнено? Каков триггер? – netikras

+0

Опять же, он не знает, когда поток закончился. Он предоставляет вам данные по мере их поступления. У TCP нет сообщений. Размер куска, который вы используете для отправки данных, не оказывает гарантированного эффекта на размер куска, который получен. На практике определенное поведение очень распространено, но на что нельзя положиться. – usr

+0

Попробуйте это, выполнив 'c.send (« a »)' два раза подряд быстрее, чем 200 мс друг от друга. Вероятно, вы получите «аа» в одном вызове recv. Это наглость в игре. – usr