@@ -147,13 +147,101 @@ public async Task SendAsync_Cancel()
147147 StopTcpServer ( server ) ;
148148 }
149149
150+ [ Fact ]
151+ public async Task ReceiveAsync_Timeout ( )
152+ {
153+ var port = 8888 ;
154+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
155+
156+ var client = CreateClient ( ) ;
157+ client . ReceiveTimeout = 100 ;
158+ client . SetDataHandler ( new MockReceiveTimeoutHandler ( ) ) ;
159+
160+ await client . ConnectAsync ( "localhost" , port ) ;
161+
162+ var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
163+ await client . SendAsync ( data ) ;
164+ await Task . Delay ( 220 ) ; // 等待接收超时
165+ }
166+
167+ [ Fact ]
168+ public async Task ReceiveAsync_Cancel ( )
169+ {
170+ var port = 8889 ;
171+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
172+
173+ var client = CreateClient ( ) ;
174+ client . SetDataHandler ( new MockReceiveTimeoutHandler ( ) ) ;
175+
176+ await client . ConnectAsync ( "localhost" , port ) ;
177+
178+ var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
179+ await client . SendAsync ( data ) ;
180+
181+ // 通过反射取消令牌
182+ var fieldInfo = client . GetType ( ) . GetField ( "_receiveCancellationTokenSource" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
183+ Assert . NotNull ( fieldInfo ) ;
184+ var tokenSource = fieldInfo . GetValue ( client ) as CancellationTokenSource ;
185+ Assert . NotNull ( tokenSource ) ;
186+ tokenSource . Cancel ( ) ;
187+ await Task . Delay ( 50 ) ;
188+ }
189+
190+ [ Fact ]
191+ public async Task ReceiveAsync_InvalidOperationException ( )
192+ {
193+ var port = 8890 ;
194+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
195+
196+ var client = CreateClient ( ) ;
197+
198+ // 未连接
199+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
200+ Assert . NotNull ( ex ) ;
201+
202+ // 反射给 _client 赋值但是未连接
203+ var fieldInfo = client . GetType ( ) . GetField ( "_client" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
204+ Assert . NotNull ( fieldInfo ) ;
205+ fieldInfo . SetValue ( client , new TcpClient ( ) ) ;
206+ ex = null ;
207+ ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
208+ Assert . NotNull ( ex ) ;
209+
210+ await client . ConnectAsync ( "localhost" , port ) ;
211+ ex = null ;
212+ ex = await Assert . ThrowsAsync < InvalidOperationException > ( async ( ) => await client . ReceiveAsync ( ) ) ;
213+
214+ //client.Close();
215+ //client.IsAutoReceive = false;
216+ //await client.ConnectAsync("localhost", port);
217+ //var data = new ReadOnlyMemory<byte>([1, 2, 3, 4, 5]);
218+ //await client.SendAsync(data);
219+ //var payload = await client.ReceiveAsync();
220+ //Assert.Equal(payload.ToArray(), [1, 2, 3, 4, 5]);
221+ }
222+
223+ [ Fact ]
224+ public async Task ReceiveAsync_Ok ( )
225+ {
226+ var port = 8891 ;
227+ var server = StartTcpServer ( port , MockSplitPackageAsync ) ;
228+
229+ var client = CreateClient ( ) ;
230+ client . IsAutoReceive = false ;
231+ await client . ConnectAsync ( "localhost" , port ) ;
232+ var data = new ReadOnlyMemory < byte > ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
233+ await client . SendAsync ( data ) ;
234+ var payload = await client . ReceiveAsync ( ) ;
235+ Assert . Equal ( payload . ToArray ( ) , [ 1 , 2 , 3 , 4 , 5 ] ) ;
236+ }
237+
150238 [ Fact ]
151239 public async Task ReceiveAsync_Error ( )
152240 {
153241 var client = CreateClient ( ) ;
154242
155243 // 测试未建立连接前调用 ReceiveAsync 方法报异常逻辑
156- var methodInfo = client . GetType ( ) . GetMethod ( "ReceiveAsync " , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
244+ var methodInfo = client . GetType ( ) . GetMethod ( "AutoReceiveAsync " , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ;
157245 Assert . NotNull ( methodInfo ) ;
158246
159247 var task = ( ValueTask ) methodInfo . Invoke ( client , null ) ! ;
@@ -549,4 +637,14 @@ public override async ValueTask<ReadOnlyMemory<byte>> SendAsync(ReadOnlyMemory<b
549637 return data ;
550638 }
551639 }
640+
641+ class MockReceiveTimeoutHandler : DataPackageHandlerBase
642+ {
643+ public override async ValueTask ReceiveAsync ( ReadOnlyMemory < byte > data , CancellationToken token = default )
644+ {
645+ // 模拟接收超时
646+ await Task . Delay ( 200 , token ) ;
647+ await base . ReceiveAsync ( data , token ) ;
648+ }
649+ }
552650}
0 commit comments