Посмотрите на трехстороннее рукопожатие TCP с точки зрения времени:
SYN
от клиента к серверу
- отправлено клиентом на
T1
- получено сервером на
T2
SYN-ACK
от сервера к клиенту
- отправлено сервером на
T3
- получено клиентом на
T4
ACK
от клиента к серверу
- отправлено клиентом на
T5
- получено сервером на
T6
Блокировка connect(2)
на клиенте возвращается на T5
, тогда как блокировка accept(2)
возвращается на T6
, а T5
строго меньше T6
. Так что да, это временное окно, в котором клиент может начать отправку данных, думая, что соединение установлено. Если клиент потерял ACK
, сервер застрял в accept(2)
. Это похоже на известную гонку с блокирующей комбинацией select(2)
/ accept(2)
.
Вы не можете предотвратить отправку клиентом до того, как accept(2)
вернется на сервер без отправки сервером чего-либо.
Обходной путь - сделать сокет сервера неблокирующим и полагаться на select(2)
/ poll(2)
/ epoll(4)
.