@@ -14,174 +14,142 @@ namespace Examples.NegotiateStreamExample
14
14
public class AsynchronousAuthenticatingTcpListener
15
15
{
16
16
public static void Main ( )
17
- {
17
+ {
18
18
// Create an IPv4 TCP/IP socket.
19
19
TcpListener listener = new TcpListener ( IPAddress . Any , 11000 ) ;
20
20
// Listen for incoming connections.
21
21
listener . Start ( ) ;
22
- while ( true )
22
+ while ( true )
23
23
{
24
- TcpClient clientRequest = null ;
24
+ TcpClient clientRequest ;
25
25
// Application blocks while waiting for an incoming connection.
26
26
// Type CNTL-C to terminate the server.
27
27
clientRequest = listener . AcceptTcpClient ( ) ;
28
28
Console . WriteLine ( "Client connected." ) ;
29
29
// A client has connected.
30
30
try
31
31
{
32
- AuthenticateClient ( clientRequest ) ;
32
+ AuthenticateClient ( clientRequest ) ;
33
33
}
34
34
catch ( Exception e )
35
35
{
36
36
Console . WriteLine ( e ) ;
37
- continue ;
38
37
}
39
38
}
40
39
}
41
- //<snippet1>
40
+
41
+ //<snippet1>
42
42
public static void AuthenticateClient ( TcpClient clientRequest )
43
43
{
44
- NetworkStream stream = clientRequest . GetStream ( ) ;
44
+ NetworkStream stream = clientRequest . GetStream ( ) ;
45
45
// Create the NegotiateStream.
46
- NegotiateStream authStream = new NegotiateStream ( stream , false ) ;
46
+ NegotiateStream authStream = new NegotiateStream ( stream , false ) ;
47
47
// Save the current client and NegotiateStream instance
48
48
// in a ClientState object.
49
49
ClientState cState = new ClientState ( authStream , clientRequest ) ;
50
50
// 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 ) ; } ) ;
69
54
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." ) ;
78
55
// Any exceptions that occurred during authentication are
79
56
// thrown by the EndAuthenticateAsServer method.
80
- try
57
+ try
81
58
{
82
59
// This call blocks until the authentication is complete.
83
- authStream . EndAuthenticateAsServer ( ar ) ;
60
+ authTask . Wait ( ) ;
84
61
}
85
62
catch ( AuthenticationException e )
86
63
{
87
64
Console . WriteLine ( e ) ;
88
65
Console . WriteLine ( "Authentication failed - closing connection." ) ;
89
- cState . Waiter . Set ( ) ;
90
66
return ;
91
67
}
92
68
catch ( Exception e )
93
69
{
94
70
Console . WriteLine ( e ) ;
95
71
Console . WriteLine ( "Closing connection." ) ;
96
- cState . Waiter . Set ( ) ;
97
72
return ;
98
73
}
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
+
99
94
// Display properties of the authenticated client.
100
95
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 ,
103
98
id . AuthenticationType
104
- ) ;
105
- cState . Waiter . Set ( ) ;
106
- }
99
+ ) ;
100
+ }
107
101
//</snippet2>
102
+
108
103
//<snippet3>
109
- public static void EndReadCallback ( IAsyncResult ar )
104
+ private static void EndReadCallback ( ClientState cState , int bytes )
110
105
{
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 ;
117
107
// Read the client message.
118
108
try
119
109
{
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
+ }
129
120
}
130
121
catch ( Exception e )
131
122
{
132
123
// A real application should do something
133
124
// useful here, such as logging the failure.
134
125
Console . WriteLine ( "Client message exception:" ) ;
135
126
Console . WriteLine ( e ) ;
136
- cState . Waiter . Set ( ) ;
137
127
return ;
138
128
}
139
129
IIdentity id = authStream . RemoteIdentity ;
140
130
Console . WriteLine ( "{0} says {1}" , id . Name , cState . Message . ToString ( ) ) ;
141
- cState . Waiter . Set ( ) ;
142
131
}
143
- //</snippet3>
132
+ //</snippet3>
144
133
}
145
134
// ClientState is the AsyncState object.
146
135
internal class ClientState
147
136
{
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
+
153
139
internal ClientState ( AuthenticatedStream a , TcpClient theClient )
154
140
{
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 ;
169
143
}
144
+ internal TcpClient Client { get ; }
145
+
146
+ internal AuthenticatedStream AuthenticatedStream { get ; }
147
+
148
+ internal byte [ ] Buffer { get ; } = new byte [ 2048 ] ;
149
+
170
150
internal StringBuilder Message
171
151
{
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 ( ) ; }
185
153
}
186
154
}
187
155
}
0 commit comments