@@ -82,24 +82,47 @@ public GarnetServerTcp(
8282 this . unixSocketPath = unixSocketPath ;
8383 this . unixSocketPermission = unixSocketPermission ;
8484
85- listenSocket = endpoint switch
85+ if ( endpoint is UnixDomainSocketEndPoint unix )
8686 {
87- UnixDomainSocketEndPoint unix => new Socket ( unix . AddressFamily , SocketType . Stream , ProtocolType . Unspecified ) ,
87+ // UDS Initialization & Cleanup
88+ listenSocket = new Socket ( unix . AddressFamily , SocketType . Stream , ProtocolType . Unspecified ) ;
89+ var socketPath = unix . ToString ( ) ;
90+ if ( File . Exists ( socketPath ) )
91+ {
92+ File . Delete ( socketPath ) ;
93+ }
94+ }
95+ else
96+ {
97+ // TCP Initialization & Port Reuse
98+ listenSocket = new Socket ( endpoint . AddressFamily , SocketType . Stream , ProtocolType . Tcp ) ;
8899
89- _ => new Socket ( endpoint . AddressFamily , SocketType . Stream , ProtocolType . Tcp )
90- } ;
100+ // Set reuse BEFORE Bind to handle TIME_WAIT states
101+ listenSocket . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
102+ }
91103
92104 acceptEventArg = new SocketAsyncEventArgs ( ) ;
93105 acceptEventArg . Completed += AcceptEventArg_Completed ;
94106 }
95107
108+ /// <summary>
109+ /// Stop listening for new connections. Frees the listening port
110+ /// without waiting for active connections to drain.
111+ /// </summary>
112+ public override void Close ( )
113+ {
114+ listenSocket . Close ( ) ;
115+ }
116+
96117 /// <summary>
97118 /// Dispose
98119 /// </summary>
99120 public override void Dispose ( )
100121 {
101- base . Dispose ( ) ;
122+ // Close listening socket to free the port and stop accepting new connections.
123+ // This also prevents new connections from arriving while DisposeActiveHandlers drains existing ones.
102124 listenSocket . Dispose ( ) ;
125+ base . Dispose ( ) ;
103126 acceptEventArg . UserToken = null ;
104127 acceptEventArg . Dispose ( ) ;
105128 networkPool ? . Dispose ( ) ;
0 commit comments