Предотвратяване на TIME_WAIT с помощта на .NET 'Async' API

Имам проблем, разработих обвивка на клиент и сървър за моя лична употреба, но за съжаление поради недостатъчни познания в мрежовото програмиране, имам проблеми с TIME_WAIT по време на свързване на клиента. Моят клиент се опитва да направи множество връзки към един и същ хост в рамките на кратък период от време, разбрах, че основната причина за това е, че се опитвам да използвам повторно сокета и той преминава в състояние TIME_WAIT, защото затварям връзка без грациозно изключване. Бих искал да знам правилния модел за затваряне на връзка с помощта на .NET сокети, в случай че използвам интензивно „Async“ API, т.е. функции като ConnectAsync, AcceptAsync, SendAsync, ReceiveAsync, DisconnectAsync (DisconnectAsync - използва повторно сокет)


person Lu4    schedule 29.11.2010    source източник
comment
Ако използвате tcp сокет, той има някаква подразбиране в Windows, вижте support.microsoft.com/kb/158474 за подробности и ако вашите клиенти не са тънки клиенти, предлагам да използвате WCF през tcp вместо това.   -  person Saeed Amiri    schedule 29.11.2010


Отговори (2)


Можете да използвате SO_REUSEADDR на сокета, за да заобиколите това. Вижте Socket.SetSocketOption за подробности, това е опцията ReuseAddress, която трябва да зададете .

Между другото, нямате предвид наистина да използвате повторно гнездото, нали? след като получите грешка, трябва да го затворите и да отворите нов.

person Steve Townsend    schedule 29.11.2010
comment
Използването на SO_REUSEADDR не е опция unixguide.net/network/socketfaq/4.5.shtml - person Lu4; 30.11.2010
comment
@Lu4 Защо? Не виждам нищо в нито една връзка, което да казва, че трябва да се избягва, само че трябва да се разберат последиците. Например това е от решаващо значение, ако искате да внедрите P2P TCP връзки зад NAT. - person Basic; 14.08.2013

Открих, че е невъзможно да предотвратя TIME_WAIT. Сървърът или клиентът ще имат проблема по всякакъв начин, в зависимост само от това кой първи инициира затваряне на връзката. Ако клиентът затваря връзката, няма да има TIME_WAIT на сървъра. Ако сървърът се затваря първи, тогава няма да има TIME_WAIT на клиента. Така че единствената опция, която остава да направите, е да използвате SO_REUSEADDR, но в този случай това все още е невъзможно да се използва повторно използвания адрес за свързване с предварително прекъснат хост

person Lu4    schedule 02.12.2010
comment
Малко стара тема... но вижте това, тъй като работи за мен при предотвратяване на TIME_WAIT: stackoverflow.com/questions/40785598/ - person cogumel0; 24.11.2016