Подскажите по нескольким вопросам.
1. К примеру сервер висящий на accept`е принимает запросы на подключение от юзеров. Для каждого принятого соединения ОС выделяет порт на том же IP к которому привязан слушающий сокет? Таким образом для одного IP может быть принято(в идеале) 65к соединений?2. Возможно ли на одной сетевухе принять/создать более 65к соединений? Если да - ткните плиз в ссылку где конкретно объясняется метода.
3. UDP протокол не гарантирует доставку, это всем известно. Но может ли случится так, что некоторый пакет придет частично?
4. Флаги для сокетов SO_RCVBUF и SO_SNDBUF get/set размер соответствующих буферов. Скажите, исходя из чего, и руководствуюсь какими принципами/основами/критериями рассчитывается размер буферов.
всем сильно благодарен.
1. да
2. Hint: на сетевухе может быть много IP адресов
3. Нет (частичный=некорректный. пакет просто дропнется)
1. На сервере на одном IP на одном порту может быть множество одновременных соединений, а не одно. В каждом соединении свой ip/порт клиента
> 1. даНет. В случае tcp/ip соединение - двусторонний туннель между endpoint'ами заданными парами ip:port:
src_ip:src_port <-> dst_ip:dst_port.
Итого 4 числа. Для однозначной идентификации туннеля, очевидно, хоть 1 из этих 4 чисел у разных туннелей должно отличаться.
Для исходящего соединения src_ip - айпи машины-клиента которая инициирует соединение (для multihome машин у которых их несколько в принципе можно явно ткнуть какой из айпи юзать), порт src_port как правило автоматически назначается ОС, хотя при наличии особых соображений можно его задать явно. Обычно ОСи назначают порты старше 1024, инкрментя на 1 по мере надобности. Очень характерно выглядит в netstat. Ну а сервер слушает на одном(а может и нескольких, если multihomed) dst_ip, и на одном конкретном dst_port.
Что отсюда следует? Клиент не может инициировать к серверу более чем 65к соединений(на 1 имеющийся айпи ифейса), иначе утратит возможность различать туннели между собой.Потому что со стороны сервера 2 числа не меняются, а со стороны клиента портов 65К ну и 1 или несколько ip.
С другой стороны, серверу ничто не мешает принимать до 65К соединений одновременно с каждого клиента: он ловит все пакеты на 1 входной порт, а вот у разных клиентов же еще и ip разный! Меняются src_ip и src_port, 2 числа для уникальной идентификации туннеля. В случае ipv4 сервер в теории мог бы принять почти (2^32) * (2^16) т.е. примерно 2^48 соединений. Реально разумеется ресурсы у сервера закончатся раньше. Поскольку хоть на входящее соединение и не выделяется новый порт, зато как минимум отслеживать состояние соединения-надо.
В случае udp - вообще нет понятия "соединение". Поэтому и такого понятия как "65к соединений" там тоже нет.
> 2. Hint: на сетевухе может быть много IP адресов
Только вот у сервера и с одним никаких проблем не будет: айпишник у клиентов то меняется, что тоже позволяет отличать туннели. Клиент не может реюзать порты на выход как раз потому что при этом все 4 числа были бы одинаковы, не давая возможности отличать туннели друг от друга(айпи сервера и клиента не меняются, порт сервера тоже, вот и остается менять исходящий порт клиента при открытии еще 1 соединения к тому же хосту, т.к. это единственное что получается менять). Но у сервера этой проблемы нет. Потому что он может различать туннели по айпи клиента и порту.
> 3. Нет (частичный=некорректный. пакет просто дропнется)
4. Буфера рассчитываются исходя из желаемой скорости и латентности. Чем выше желаемая скорость передачи данных и латентность сети и/или обслуживания сокетов, тем жирнее надо буфер чтобы удержать в нем то что навалилось за это время. Вообще, однозначно определить оптимальный размер буфера нетривиально. Для 10 Гбит эзернета между соседними машинами оптимальный буфер будет немного иной чем для тощего adsl с 128 кбит аплоада. А какой линк подсунут - заранее неизвестно.А, ну и операционка имеет свое мнение о том сколько еще можно вам дать, а сколько уже больно жирно(для некоторых типов соединений этот параметр ОС еще и тюнят для макс. производительности).
Таким образом для одного IP может быть принято(в идеале) 65к соединений?
>> 1. да
> Нет. В случае tcp/ip соединение - двусторонний туннель между endpoint'ами заданными парами
> ip:port:
> Что отсюда следует? Клиент не может инициировать к серверу более чем 65к
> соединенийВы сами себе противоречите, любезный.
> Таким образом для одного IP может быть принято(в идеале) 65к соединений?Да, на 1 порт 1 айпишника какой-то машины с вашей стороны не может быть более 65К соединений. Потом у вас кончатся порты назначаемые на вашу сторону исходящего соединения и не получится создавать соединения которые чем-то отличаются от предыдущих.
>> Что отсюда следует? Клиент не может инициировать к серверу более чем 65к соединений
> Вы сами себе противоречите, любезный.Wrong: вы забываете что сервер может обслуживать более 1 клиента. Айпи клиентов будет разный, поэтому соединений принятых сервером может быть и более 65К. Например, если клиентов 10, с 10 разных айпи в теории на сервер может прийти до 650К уникально идентифицируемых соединений.
>> Таким образом для одного IP может быть принято(в идеале) 65к соединений?
> Да, на 1 порт 1 айпишника какой-то машины с вашей стороны не может быть более 65К соединений.Да ну!? А если 1000500 виртуалок + 1000000 LXC контейнеров + вы ещё и NATом работаете.
---Короче, pupkin, забей на теорию. Бабло решает все проблемы.
> Подскажите по нескольким вопросам.
> 1. К примеру сервер висящий на accept`еСервер не висит на accept()!!!
> принимает запросы на подключение от
> юзеров. Для каждого принятого соединения ОС выделяет порт на том же
> IP к которому привязан слушающий сокет? Таким образом для одного IP
> может быть принято(в идеале) 65к соединений?4294967295
> 2. Возможно ли на одной сетевухе принять/создать более 65к соединений?
> Если да - ткните плиз в ссылку где конкретно объясняется метода.
/*
* Maximum number of SYN_RECV sockets in queue per LISTEN socket.
* One SYN_RECV socket costs about 80bytes on a 32bit machine.
* It would be better to replace it with a global counter for all sockets
* but then some measure against one socket starving all other sockets
* would be needed.
*
* It was 128 by default. Experiments with real servers show, that
* it is absolutely not enough even at 100conn/sec. 256 cures most
* of problems. This value is adjusted to 128 for very small machines
* (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
* Note : Dont forget somaxconn that may limit backlog too.
*/
Documentation/networking/ip-sysctl.txt
somaxconn - INTEGER
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
Defaults to 128. See also tcp_max_syn_backlog for additional tuning
for TCP sockets.> 3. UDP протокол не гарантирует доставку, это всем известно. Но может ли
> случится так, что некоторый пакет придет частично?Прибьёт и попросит повтор.
> исходя из чего, и руководствуюсь какими принципами/основами/критериями рассчитывается
> размер буферов.
case SO_SNDBUF:
/* Don't error on this BSD doesn't and if you think
about it this is right. Otherwise apps have to
play 'guess the biggest size' games. RCVBUF/SNDBUF
are treated in BSD as hints */
if (val > sysctl_wmem_max)
val = sysctl_wmem_max;
set_sndbuf:
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
if ((val * 2) < SOCK_MIN_SNDBUF)
sk->sk_sndbuf = SOCK_MIN_SNDBUF;
else
sk->sk_sndbuf = val * 2;/*
* Wake up sending tasks if we
* upped the value.
*/
sk->sk_write_space(sk);
> всем сильно благодарен.