3
3
4
4
using System . Collections . Generic ;
5
5
using System . Threading ;
6
+ using System . Threading . Tasks ;
6
7
using Xunit ;
8
+ using Xunit . Abstractions ;
7
9
8
10
namespace System . Net . Sockets . Tests
9
11
{
10
- public class ReceiveMessageFrom
12
+ public abstract class ReceiveMessageFrom < T > : SocketTestHelperBase < T > where T : SocketHelperBase , new ( )
11
13
{
12
- [ OuterLoop ]
13
- [ Theory ]
14
- [ InlineData ( false ) ]
15
- [ InlineData ( true ) ]
16
- public void Success ( bool forceNonBlocking )
17
- {
18
- if ( Socket . OSSupportsIPv4 )
19
- {
20
- using ( Socket receiver = new Socket ( AddressFamily . InterNetwork , SocketType . Dgram , ProtocolType . Udp ) )
21
- {
22
- int port = receiver . BindToAnonymousPort ( IPAddress . Loopback ) ;
23
- receiver . SetSocketOption ( SocketOptionLevel . IP , SocketOptionName . PacketInformation , true ) ;
24
-
25
- receiver . ForceNonBlocking ( forceNonBlocking ) ;
26
-
27
- Socket sender = new Socket ( AddressFamily . InterNetwork , SocketType . Dgram , ProtocolType . Udp ) ;
28
- sender . Bind ( new IPEndPoint ( IPAddress . Loopback , 0 ) ) ;
29
-
30
- sender . ForceNonBlocking ( forceNonBlocking ) ;
31
-
32
- sender . SendTo ( new byte [ 1024 ] , new IPEndPoint ( IPAddress . Loopback , port ) ) ;
14
+ protected ReceiveMessageFrom ( ITestOutputHelper output ) : base ( output ) { }
33
15
34
- IPPacketInformation packetInformation ;
35
- SocketFlags flags = SocketFlags . None ;
36
- EndPoint remoteEP = new IPEndPoint ( IPAddress . Any , 0 ) ;
37
-
38
- int len = receiver . ReceiveMessageFrom ( new byte [ 1024 ] , 0 , 1024 , ref flags , ref remoteEP , out packetInformation ) ;
39
-
40
- Assert . Equal ( 1024 , len ) ;
41
- Assert . Equal ( sender . LocalEndPoint , remoteEP ) ;
42
- Assert . Equal ( ( ( IPEndPoint ) sender . LocalEndPoint ) . Address , packetInformation . Address ) ;
43
-
44
- sender . Dispose ( ) ;
45
- }
46
- }
47
- }
48
-
49
- [ OuterLoop ]
50
16
[ Theory ]
51
17
[ InlineData ( false ) ]
52
18
[ InlineData ( true ) ]
53
- public void Success_IPv6 ( bool forceNonBlocking )
19
+ public async Task ReceiveSentMessages_Success ( bool ipv4 )
54
20
{
55
- if ( Socket . OSSupportsIPv6 )
56
- {
57
- using ( Socket receiver = new Socket ( AddressFamily . InterNetworkV6 , SocketType . Dgram , ProtocolType . Udp ) )
58
- {
59
- int port = receiver . BindToAnonymousPort ( IPAddress . IPv6Loopback ) ;
60
- receiver . SetSocketOption ( SocketOptionLevel . IPv6 , SocketOptionName . PacketInformation , true ) ;
21
+ const int DatagramSize = 256 ;
22
+ const int DatagramsToSend = 16 ;
61
23
62
- receiver . ForceNonBlocking ( forceNonBlocking ) ;
24
+ IPAddress address = ipv4 ? IPAddress . Loopback : IPAddress . IPv6Loopback ;
25
+ using Socket receiver = new Socket ( address . AddressFamily , SocketType . Dgram , ProtocolType . Udp ) ;
26
+ using Socket sender = new Socket ( address . AddressFamily , SocketType . Dgram , ProtocolType . Udp ) ;
63
27
64
- Socket sender = new Socket ( AddressFamily . InterNetworkV6 , SocketType . Dgram , ProtocolType . Udp ) ;
65
- sender . Bind ( new IPEndPoint ( IPAddress . IPv6Loopback , 0 ) ) ;
28
+ receiver . SetSocketOption ( ipv4 ? SocketOptionLevel . IP : SocketOptionLevel . IPv6 , SocketOptionName . PacketInformation , true ) ;
29
+ ConfigureNonBlocking ( sender ) ;
30
+ ConfigureNonBlocking ( receiver ) ;
66
31
67
- sender . ForceNonBlocking ( forceNonBlocking ) ;
32
+ receiver . BindToAnonymousPort ( address ) ;
33
+ sender . BindToAnonymousPort ( address ) ;
68
34
69
- sender . SendTo ( new byte [ 1024 ] , new IPEndPoint ( IPAddress . IPv6Loopback , port ) ) ;
35
+ byte [ ] sendBuffer = new byte [ DatagramSize ] ;
36
+ byte [ ] receiveBuffer = new byte [ DatagramSize ] ;
37
+ Random rnd = new Random ( 0 ) ;
70
38
71
- IPPacketInformation packetInformation ;
72
- SocketFlags flags = SocketFlags . None ;
73
- EndPoint remoteEP = new IPEndPoint ( IPAddress . IPv6Any , 0 ) ;
39
+ IPEndPoint remoteEp = new IPEndPoint ( ipv4 ? IPAddress . Any : IPAddress . IPv6Any , 0 ) ;
74
40
75
- int len = receiver . ReceiveMessageFrom ( new byte [ 1024 ] , 0 , 1024 , ref flags , ref remoteEP , out packetInformation ) ;
41
+ for ( int i = 0 ; i < DatagramsToSend ; i ++ )
42
+ {
43
+ rnd . NextBytes ( sendBuffer ) ;
44
+ sender . SendTo ( sendBuffer , receiver . LocalEndPoint ) ;
76
45
77
- Assert . Equal ( 1024 , len ) ;
78
- Assert . Equal ( sender . LocalEndPoint , remoteEP ) ;
79
- Assert . Equal ( ( ( IPEndPoint ) sender . LocalEndPoint ) . Address , packetInformation . Address ) ;
46
+ SocketReceiveMessageFromResult result = await ReceiveMessageFromAsync ( receiver , receiveBuffer , remoteEp ) ;
47
+ IPPacketInformation packetInformation = result . PacketInformation ;
80
48
81
- sender . Dispose ( ) ;
82
- }
49
+ Assert . Equal ( DatagramSize , result . ReceivedBytes ) ;
50
+ AssertExtensions . SequenceEqual ( sendBuffer , receiveBuffer ) ;
51
+ Assert . Equal ( sender . LocalEndPoint , result . RemoteEndPoint ) ;
52
+ Assert . Equal ( ( ( IPEndPoint ) sender . LocalEndPoint ) . Address , packetInformation . Address ) ;
83
53
}
84
54
}
55
+ }
85
56
86
- [ OuterLoop ]
87
- [ Theory ]
88
- [ InlineData ( false ) ]
89
- [ InlineData ( true ) ]
90
- public void Success_APM ( bool ipv4 )
91
- {
92
- AddressFamily family ;
93
- IPAddress loopback , any ;
94
- SocketOptionLevel level ;
95
- if ( ipv4 )
96
- {
97
- if ( ! Socket . OSSupportsIPv4 ) return ;
98
- family = AddressFamily . InterNetwork ;
99
- loopback = IPAddress . Loopback ;
100
- any = IPAddress . Any ;
101
- level = SocketOptionLevel . IP ;
102
- }
103
- else
104
- {
105
- if ( ! Socket . OSSupportsIPv6 ) return ;
106
- family = AddressFamily . InterNetworkV6 ;
107
- loopback = IPAddress . IPv6Loopback ;
108
- any = IPAddress . IPv6Any ;
109
- level = SocketOptionLevel . IPv6 ;
110
- }
111
-
112
- using ( var receiver = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) )
113
- using ( var sender = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) )
114
- {
115
- int port = receiver . BindToAnonymousPort ( loopback ) ;
116
- receiver . SetSocketOption ( level , SocketOptionName . PacketInformation , true ) ;
117
- sender . Bind ( new IPEndPoint ( loopback , 0 ) ) ;
57
+ public sealed class ReceiveMessageFrom_Sync : ReceiveMessageFrom < SocketHelperArraySync >
58
+ {
59
+ public ReceiveMessageFrom_Sync ( ITestOutputHelper output ) : base ( output ) { }
60
+ }
118
61
119
- sender . SendTo ( new byte [ 1024 ] , new IPEndPoint ( loopback , port ) ) ;
62
+ public sealed class ReceiveMessageFrom_SyncForceNonBlocking : ReceiveMessageFrom < SocketHelperSyncForceNonBlocking >
63
+ {
64
+ public ReceiveMessageFrom_SyncForceNonBlocking ( ITestOutputHelper output ) : base ( output ) { }
65
+ }
120
66
121
- IPPacketInformation packetInformation ;
122
- SocketFlags flags = SocketFlags . None ;
123
- EndPoint remoteEP = new IPEndPoint ( any , 0 ) ;
67
+ public sealed class ReceiveMessageFrom_Apm : ReceiveMessageFrom < SocketHelperApm >
68
+ {
69
+ public ReceiveMessageFrom_Apm ( ITestOutputHelper output ) : base ( output ) { }
70
+ }
124
71
125
- IAsyncResult ar = receiver . BeginReceiveMessageFrom ( new byte [ 1024 ] , 0 , 1024 , flags , ref remoteEP , null , null ) ;
126
- int len = receiver . EndReceiveMessageFrom ( ar , ref flags , ref remoteEP , out packetInformation ) ;
72
+ public sealed class ReceiveMessageFrom_Task : ReceiveMessageFrom < SocketHelperTask >
73
+ {
74
+ public ReceiveMessageFrom_Task ( ITestOutputHelper output ) : base ( output ) { }
75
+ }
127
76
128
- Assert . Equal ( 1024 , len ) ;
129
- Assert . Equal ( sender . LocalEndPoint , remoteEP ) ;
130
- Assert . Equal ( ( ( IPEndPoint ) sender . LocalEndPoint ) . Address , packetInformation . Address ) ;
131
- }
132
- }
77
+ public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom < SocketHelperEap >
78
+ {
79
+ public ReceiveMessageFrom_Eap ( ITestOutputHelper output ) : base ( output ) { }
133
80
134
- [ OuterLoop ]
135
81
[ Theory ]
136
82
[ InlineData ( false , 0 ) ]
137
83
[ InlineData ( false , 1 ) ]
138
84
[ InlineData ( false , 2 ) ]
139
85
[ InlineData ( true , 0 ) ]
140
86
[ InlineData ( true , 1 ) ]
141
87
[ InlineData ( true , 2 ) ]
142
- public void Success_EventArgs ( bool ipv4 , int bufferMode )
88
+ public void ReceiveSentMessages_ReuseEventArgs_Success ( bool ipv4 , int bufferMode )
143
89
{
90
+ const int DatagramsToSend = 30 ;
91
+ const int TimeoutMs = 30_000 ;
92
+
144
93
AddressFamily family ;
145
94
IPAddress loopback , any ;
146
95
SocketOptionLevel level ;
147
96
if ( ipv4 )
148
97
{
149
- if ( ! Socket . OSSupportsIPv4 ) return ;
150
98
family = AddressFamily . InterNetwork ;
151
99
loopback = IPAddress . Loopback ;
152
100
any = IPAddress . Any ;
153
101
level = SocketOptionLevel . IP ;
154
102
}
155
103
else
156
104
{
157
- if ( ! Socket . OSSupportsIPv6 ) return ;
158
105
family = AddressFamily . InterNetworkV6 ;
159
106
loopback = IPAddress . IPv6Loopback ;
160
107
any = IPAddress . IPv6Any ;
161
108
level = SocketOptionLevel . IPv6 ;
162
109
}
163
110
164
- using ( var receiver = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) )
165
- using ( var sender = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) )
166
- using ( var saea = new SocketAsyncEventArgs ( ) )
167
- {
168
- int port = receiver . BindToAnonymousPort ( loopback ) ;
169
- receiver . SetSocketOption ( level , SocketOptionName . PacketInformation , true ) ;
170
- sender . Bind ( new IPEndPoint ( loopback , 0 ) ) ;
111
+ using var receiver = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) ;
112
+ using var sender = new Socket ( family , SocketType . Dgram , ProtocolType . Udp ) ;
113
+ using var saea = new SocketAsyncEventArgs ( ) ;
114
+ var completed = new ManualResetEventSlim ( ) ;
115
+ saea . Completed += delegate { completed . Set ( ) ; } ;
171
116
172
- saea . RemoteEndPoint = new IPEndPoint ( any , 0 ) ;
117
+ int port = receiver . BindToAnonymousPort ( loopback ) ;
118
+ receiver . SetSocketOption ( level , SocketOptionName . PacketInformation , true ) ;
119
+ sender . Bind ( new IPEndPoint ( loopback , 0 ) ) ;
120
+ saea . RemoteEndPoint = new IPEndPoint ( any , 0 ) ;
121
+
122
+ for ( int i = 0 ; i < DatagramsToSend ; i ++ )
123
+ {
173
124
switch ( bufferMode )
174
125
{
175
126
case 0 : // single buffer
@@ -190,17 +141,35 @@ public void Success_EventArgs(bool ipv4, int bufferMode)
190
141
break ;
191
142
}
192
143
193
- var mres = new ManualResetEventSlim ( ) ;
194
- saea . Completed += delegate { mres . Set ( ) ; } ;
195
-
196
144
bool pending = receiver . ReceiveMessageFromAsync ( saea ) ;
197
145
sender . SendTo ( new byte [ 1024 ] , new IPEndPoint ( loopback , port ) ) ;
198
- if ( pending ) Assert . True ( mres . Wait ( 30000 ) , "Expected operation to complete within timeout" ) ;
146
+ if ( pending ) Assert . True ( completed . Wait ( TimeoutMs ) , "Expected operation to complete within timeout" ) ;
147
+ completed . Reset ( ) ;
199
148
200
149
Assert . Equal ( 1024 , saea . BytesTransferred ) ;
201
150
Assert . Equal ( sender . LocalEndPoint , saea . RemoteEndPoint ) ;
202
151
Assert . Equal ( ( ( IPEndPoint ) sender . LocalEndPoint ) . Address , saea . ReceiveMessageFromPacketInfo . Address ) ;
203
- }
152
+ }
204
153
}
205
154
}
155
+
156
+ public sealed class ReceiveMessageFrom_SpanSync : ReceiveMessageFrom < SocketHelperSpanSync >
157
+ {
158
+ public ReceiveMessageFrom_SpanSync ( ITestOutputHelper output ) : base ( output ) { }
159
+ }
160
+
161
+ public sealed class ReceiveMessageFrom_SpanSyncForceNonBlocking : ReceiveMessageFrom < SocketHelperSpanSyncForceNonBlocking >
162
+ {
163
+ public ReceiveMessageFrom_SpanSyncForceNonBlocking ( ITestOutputHelper output ) : base ( output ) { }
164
+ }
165
+
166
+ public sealed class ReceiveMessageFrom_MemoryArrayTask : ReceiveMessageFrom < SocketHelperMemoryArrayTask >
167
+ {
168
+ public ReceiveMessageFrom_MemoryArrayTask ( ITestOutputHelper output ) : base ( output ) { }
169
+ }
170
+
171
+ public sealed class ReceiveMessageFrom_MemoryNativeTask : ReceiveMessageFrom < SocketHelperMemoryNativeTask >
172
+ {
173
+ public ReceiveMessageFrom_MemoryNativeTask ( ITestOutputHelper output ) : base ( output ) { }
174
+ }
206
175
}
0 commit comments