> В случае блокирующего send задумается. Но если сервер > многопоточный на работе сервера это никак не скажется. > В случае неблокирующего send просто пошлет не все, о чем и > скажет вызывающей апликухе. И будет посылать не все пока в > буфера tcp стека не освободится место.
но открытый ресурс-сокет будет держаться, пока клиент все не прочтет?
Сервер ждет прихода входящего соединения, и когда клиент подсоединится, пишет туда 100 байт.
Есть TCP клиент.
TCP клиент создает сокет на соединение с сервером, читает оттуда первые, допустим 10 байт, и больше ничего не делает. Сознательно спит.
Вопрос: как в этом случае будет работать стек TCP на клиенте и сервере? Сервер "подвиснет", ожидая, пока клиент "выкачает" оставшиеся 90 байт или же сервер всё отгрузит на клиента (а канал в порядке), там все это сбуферизируется и это добро отдадут клиенту, когда он осуществит следующее чтение?
Нарывались на обратную ситуацию.19.10.05 13:41 Автор: cybervlad <cybervlad> Статус: Elderman
> Вопрос: как в этом случае будет работать стек TCP на > клиенте и сервере? Сервер "подвиснет", ожидая, пока клиент > "выкачает" оставшиеся 90 байт или же сервер всё отгрузит на > клиента (а канал в порядке), там все это сбуферизируется и > это добро отдадут клиенту, когда он осуществит следующее > чтение? Нарывались на обратную ситуацию.
Типа, клиент пишет в сокет "GET DATA/OK"
Сервер ему в ответ "ЛОВИ DATA 2048/OK" и пихает в сокет 2048 байт.
Клиент, прочитав"ЛОВИ DATA 2048/OK" готовит буфер размером 2048 байти делает блочное чтение из сокета 2048 байт. Функция чтения при этом возвращает реально прочитанное количество байт. Так вот, очень часто оно оказывалось меньше 2048. Повторный вызов функции "дочитывал" остатки. Иногда требовалось и более 2 вызовов. Объем считанных за раз данных никак не коррелировал с MTU. Т.е. как оно там в стеке работает - х.з. В результате просто поставили цикл типа while (dataread<2048).
Насчет зависания. Если сокет открыть как keepalive, то он будет периодически "взбадриваться" стеком и оставаться открытым. В противном случае, если по нему не гнать данных, он закроется по тайм-ауту через некоторое время.
Я бы сделал так:
1) На прикладном уровне ввел бы подтверждение со стороны клиента о приеме. Т.е. типа сервер плюнул в сокет данные, сделал fflush и ждет определенное время ответа "Ok".
2) Если ответа не пришло в течение заданного времени, закрыть сокет нафиг, проблемы клиента (на уровне стека он некоторое время будет close_wait)
3) Если от клиента пришло подтверждение, но он больше ничего не просит и сокет не закрывает, то по тайм-ауту сервер закрывает сокет.
setsockopt/TCP_NODELAY может сделать поведение более коррелирующим. Я его использую для протоколов работающих в режиме диалога -запрос/ожидание ответа -получается быстрее. Но вообще не надо на это завязываться - это потоковый протокол и данные имеют полное право вообще по одному байту приходить.
Это зависит от размера приемного TCP буффера клиента -- стек...18.10.05 16:17 Автор: lunc <Alexander Krizhanovsky> Статус: Member
> Вопрос: как в этом случае будет работать стек TCP на > клиенте и сервере? Сервер "подвиснет", ожидая, пока клиент > "выкачает" оставшиеся 90 байт или же сервер всё отгрузит на > клиента (а канал в порядке), там все это сбуферизируется и > это добро отдадут клиенту, когда он осуществит следующее > чтение?
Это зависит от размера приемного TCP буффера клиента -- стек его заполняет, объявляет win=0 и больше ему ничего отправляться не должно. Пока место в буффере есть -- сервер может отправлять.
Вроде бы 100 байт влезут в один пакет. Поэтому сервер...18.10.05 15:36 Автор: ZloyShaman <ZloyShaman> Статус: Elderman
Вроде бы 100 байт влезут в один пакет. Поэтому сервер получит подтверждение о том, что байты с 1 по 100 были доставлены. Сколько же будет читать клиент из потока - его личное дело.
Наверное так.
100 - это я для примера взял. А в ситуации, если сервер...18.10.05 15:46 Автор: paganoid Статус: Member
> Вроде бы 100 байт влезут в один пакет. Поэтому сервер > получит подтверждение о том, что байты с 1 по 100 были > доставлены. Сколько же будет читать клиент из потока - его > личное дело. > Наверное так.
100 - это я для примера взял. А в ситуации, если сервер записал 100000 байт, а клиент прочёл 10 и молчит, от сервера уйдет пакет в 100 байт (ну если это размер TCP пакета), а остальные 999900 останутся висеть в буфере отправки?
В случае блокирующего send задумается. Но если сервер многопоточный на работе сервера это никак не скажется.
В случае неблокирующего send просто пошлет не все, о чем и скажет вызывающей апликухе. И будет посылать не все пока в буфера tcp стека не освободится место.
но открытый ресурс-сокет будет держаться, пока клиент все не...18.10.05 17:01 Автор: paganoid Статус: Member
> В случае блокирующего send задумается. Но если сервер > многопоточный на работе сервера это никак не скажется. > В случае неблокирующего send просто пошлет не все, о чем и > скажет вызывающей апликухе. И будет посылать не все пока в > буфера tcp стека не освободится место.
но открытый ресурс-сокет будет держаться, пока клиент все не прочтет?
сокет будет держаться пока его не закроет сервер в любом случае.18.10.05 18:28 Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 18.10.05 18:29 Количество правок: 1
А если ты про то что будет если даные ожидают посылки клиенту а сервер делает closesocket? В этом случае тут все зависит от того как настроена опция linger на сокете.