@@ -14,174 +14,142 @@ namespace Examples.NegotiateStreamExample
1414 public class AsynchronousAuthenticatingTcpListener
1515 {
1616 public static void Main ( )
17- {
17+ {
1818 // Create an IPv4 TCP/IP socket.
1919 TcpListener listener = new TcpListener ( IPAddress . Any , 11000 ) ;
2020 // Listen for incoming connections.
2121 listener . Start ( ) ;
22- while ( true )
22+ while ( true )
2323 {
24- TcpClient clientRequest = null ;
24+ TcpClient clientRequest ;
2525 // Application blocks while waiting for an incoming connection.
2626 // Type CNTL-C to terminate the server.
2727 clientRequest = listener . AcceptTcpClient ( ) ;
2828 Console . WriteLine ( "Client connected." ) ;
2929 // A client has connected.
3030 try
3131 {
32- AuthenticateClient ( clientRequest ) ;
32+ AuthenticateClient ( clientRequest ) ;
3333 }
3434 catch ( Exception e )
3535 {
3636 Console . WriteLine ( e ) ;
37- continue ;
3837 }
3938 }
4039 }
41- //<snippet1>
40+
41+ //<snippet1>
4242 public static void AuthenticateClient ( TcpClient clientRequest )
4343 {
44- NetworkStream stream = clientRequest . GetStream ( ) ;
44+ NetworkStream stream = clientRequest . GetStream ( ) ;
4545 // Create the NegotiateStream.
46- NegotiateStream authStream = new NegotiateStream ( stream , false ) ;
46+ NegotiateStream authStream = new NegotiateStream ( stream , false ) ;
4747 // Save the current client and NegotiateStream instance
4848 // in a ClientState object.
4949 ClientState cState = new ClientState ( authStream , clientRequest ) ;
5050 // Listen for the client authentication request.
51- authStream . BeginAuthenticateAsServer (
52- new AsyncCallback ( EndAuthenticateCallback ) ,
53- cState
54- ) ;
55- // Wait until the authentication completes.
56- cState . Waiter . WaitOne ( ) ;
57- cState . Waiter . Reset ( ) ;
58- authStream . BeginRead ( cState . Buffer , 0 , cState . Buffer . Length ,
59- new AsyncCallback ( EndReadCallback ) ,
60- cState ) ;
61- cState . Waiter . WaitOne ( ) ;
62- // Finished with the current client.
63- authStream . Close ( ) ;
64- clientRequest . Close ( ) ;
65- }
66- //</snippet1>
67- // The following method is invoked by the
68- // BeginAuthenticateAsServer callback delegate.
51+ Task authTask = authStream
52+ . AuthenticateAsServerAsync ( )
53+ . ContinueWith ( task => { EndAuthenticateCallback ( cState ) ; } ) ;
6954
70- //<snippet2>
71- public static void EndAuthenticateCallback ( IAsyncResult ar )
72- {
73- // Get the saved data.
74- ClientState cState = ( ClientState ) ar . AsyncState ;
75- TcpClient clientRequest = cState . Client ;
76- NegotiateStream authStream = ( NegotiateStream ) cState . AuthenticatedStream ;
77- Console . WriteLine ( "Ending authentication." ) ;
7855 // Any exceptions that occurred during authentication are
7956 // thrown by the EndAuthenticateAsServer method.
80- try
57+ try
8158 {
8259 // This call blocks until the authentication is complete.
83- authStream . EndAuthenticateAsServer ( ar ) ;
60+ authTask . Wait ( ) ;
8461 }
8562 catch ( AuthenticationException e )
8663 {
8764 Console . WriteLine ( e ) ;
8865 Console . WriteLine ( "Authentication failed - closing connection." ) ;
89- cState . Waiter . Set ( ) ;
9066 return ;
9167 }
9268 catch ( Exception e )
9369 {
9470 Console . WriteLine ( e ) ;
9571 Console . WriteLine ( "Closing connection." ) ;
96- cState . Waiter . Set ( ) ;
9772 return ;
9873 }
74+
75+ Task < int > readTask = authStream
76+ . ReadAsync ( cState . Buffer , 0 , cState . Buffer . Length ) ;
77+
78+ readTask
79+ . ContinueWith ( ( task ) => { EndReadCallback ( cState , task . Result ) ; } )
80+ . Wait ( ) ;
81+ // Finished with the current client.
82+ authStream . Close ( ) ;
83+ clientRequest . Close ( ) ;
84+ }
85+ //</snippet1>
86+
87+ //<snippet2>
88+ private static void EndAuthenticateCallback ( ClientState cState )
89+ {
90+ // Get the saved data.
91+ NegotiateStream authStream = ( NegotiateStream ) cState . AuthenticatedStream ;
92+ Console . WriteLine ( "Ending authentication." ) ;
93+
9994 // Display properties of the authenticated client.
10095 IIdentity id = authStream . RemoteIdentity ;
101- Console . WriteLine ( "{0} was authenticated using {1}." ,
102- id . Name ,
96+ Console . WriteLine ( "{0} was authenticated using {1}." ,
97+ id . Name ,
10398 id . AuthenticationType
104- ) ;
105- cState . Waiter . Set ( ) ;
106- }
99+ ) ;
100+ }
107101//</snippet2>
102+
108103//<snippet3>
109- public static void EndReadCallback ( IAsyncResult ar )
104+ private static void EndReadCallback ( ClientState cState , int bytes )
110105 {
111- // Get the saved data.
112- ClientState cState = ( ClientState ) ar . AsyncState ;
113- TcpClient clientRequest = cState . Client ;
114- NegotiateStream authStream = ( NegotiateStream ) cState . AuthenticatedStream ;
115- // Get the buffer that stores the message sent by the client.
116- int bytes = - 1 ;
106+ NegotiateStream authStream = ( NegotiateStream ) cState . AuthenticatedStream ;
117107 // Read the client message.
118108 try
119109 {
120- bytes = authStream . EndRead ( ar ) ;
121- cState . Message . Append ( Encoding . UTF8 . GetChars ( cState . Buffer , 0 , bytes ) ) ;
122- if ( bytes != 0 )
123- {
124- authStream . BeginRead ( cState . Buffer , 0 , cState . Buffer . Length ,
125- new AsyncCallback ( EndReadCallback ) ,
126- cState ) ;
127- return ;
128- }
110+ cState . Message . Append ( Encoding . UTF8 . GetChars ( cState . Buffer , 0 , bytes ) ) ;
111+ if ( bytes != 0 )
112+ {
113+ Task < int > readTask = authStream . ReadAsync ( cState . Buffer , 0 , cState . Buffer . Length ) ;
114+ readTask
115+ . ContinueWith ( task => { EndReadCallback ( cState , task . Result ) ; } )
116+ . Wait ( ) ;
117+
118+ return ;
119+ }
129120 }
130121 catch ( Exception e )
131122 {
132123 // A real application should do something
133124 // useful here, such as logging the failure.
134125 Console . WriteLine ( "Client message exception:" ) ;
135126 Console . WriteLine ( e ) ;
136- cState . Waiter . Set ( ) ;
137127 return ;
138128 }
139129 IIdentity id = authStream . RemoteIdentity ;
140130 Console . WriteLine ( "{0} says {1}" , id . Name , cState . Message . ToString ( ) ) ;
141- cState . Waiter . Set ( ) ;
142131 }
143- //</snippet3>
132+ //</snippet3>
144133 }
145134 // ClientState is the AsyncState object.
146135 internal class ClientState
147136 {
148- private AuthenticatedStream authStream = null ;
149- private TcpClient client = null ;
150- byte [ ] buffer = new byte [ 2048 ] ;
151- StringBuilder message = null ;
152- ManualResetEvent waiter = new ManualResetEvent ( false ) ;
137+ private StringBuilder _message = null ;
138+
153139 internal ClientState ( AuthenticatedStream a , TcpClient theClient )
154140 {
155- authStream = a ;
156- client = theClient ;
157- }
158- internal TcpClient Client
159- {
160- get { return client ; }
161- }
162- internal AuthenticatedStream AuthenticatedStream
163- {
164- get { return authStream ; }
165- }
166- internal byte [ ] Buffer
167- {
168- get { return buffer ; }
141+ AuthenticatedStream = a ;
142+ Client = theClient ;
169143 }
144+ internal TcpClient Client { get ; }
145+
146+ internal AuthenticatedStream AuthenticatedStream { get ; }
147+
148+ internal byte [ ] Buffer { get ; } = new byte [ 2048 ] ;
149+
170150 internal StringBuilder Message
171151 {
172- get
173- {
174- if ( message == null )
175- message = new StringBuilder ( ) ;
176- return message ;
177- }
178- }
179- internal ManualResetEvent Waiter
180- {
181- get
182- {
183- return waiter ;
184- }
152+ get { return _message ??= new StringBuilder ( ) ; }
185153 }
186154 }
187155}
0 commit comments