Правила, разрешающие повторное использование локального порта приложением

Для TCP-сервера со следующей структурой:

main(){
    socket();
    bind();
    listen();
    while(1){
       accept();
       fork();
       if(child)
          Process;
    }
}

Он создает новый сокет для каждого клиента и взаимодействует со всеми клиентами, используя один и тот же порт. Таким образом, все сокеты привязываются к одному и тому же порту.

Я наткнулся на следующие комментарии при чтении код ядра (2.6.33.5):

48/* There are a few simple rules, which allow for local port reuse by
49 * an application.  In essence:
50 *
51 *      1) Sockets bound to different interfaces may share a local port.
52 *         Failing that, goto test 2.
53 *      2) If all sockets have sk->sk_reuse set, and none of them are in
54 *         TCP_LISTEN state, the port may be shared.
55 *         Failing that, goto test 3.
56 *      3) If all sockets are bound to a specific inet_sk(sk)->rcv_saddr local
57 *         address, and none of them are the same, the port may be
58 *         shared.
59 *         Failing this, the port cannot be shared.
60 *

Итак, для приведенного выше TCP-сервера это третье правило, которому он соответствует?


person sliter    schedule 15.12.2011    source источник
comment
Независимо от реализации Linux TCP-соединение отличается пятеркой: (протокол, локальный адрес, локальный порт, удаленный адрес, удаленный порт).   -  person Brian Cain    schedule 15.12.2011


Ответы (1)


В этой игре участвует 1 плюс N сокетов.

1 сокет прослушивания, который был передан bind() и listen(). Только этот сокет привязан к порту, который слушает сервер.

2 Все N подключенных сокетов, созданных N «процессами» клиентов, подключающихся к серверу и возвращаемых accept(). Эти сокеты обслуживают соединения с клиентами. Такие сокеты не прослушивают в том смысле, в каком это делает прослушивающий сокет.

Процитированные вами правила применяются только к слушающему сокету.

Таким образом, если вы запускаете только один экземпляр своего сервера, третье правило не применяется, поскольку оно bind()s только один сокет listen() на порту сервера.

person alk    schedule 23.12.2011