|
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license.
|
3 | 3 |
|
4 | 4 | using System.Diagnostics;
|
| 5 | +using System.Globalization; |
5 | 6 | using System.IO;
|
6 | 7 | using System.IO.Pipes;
|
7 | 8 | using System.Runtime.Serialization.Formatters.Binary;
|
@@ -265,7 +266,6 @@ public void SocketCtr_SocketInformation_WhenProtocolInformationTooShort_Throws()
|
265 | 266 | public abstract class PolymorphicTests<T> where T : SocketHelperBase, new()
|
266 | 267 | {
|
267 | 268 | private static readonly T Helper = new T();
|
268 |
| - private readonly string _ipcPipeName = Path.GetRandomFileName(); |
269 | 269 |
|
270 | 270 | private static void WriteSocketInfo(Stream stream, SocketInformation socketInfo)
|
271 | 271 | {
|
@@ -317,44 +317,58 @@ public async Task DuplicateAndClose_TcpServerHandler(AddressFamily addressFamily
|
317 | 317 | // Async is allowed on the listener:
|
318 | 318 | using Socket handlerOriginal = await listener.AcceptAsync();
|
319 | 319 |
|
320 |
| - // pipe used to exchange socket info |
321 |
| - await using NamedPipeServerStream pipeServerStream = |
322 |
| - new NamedPipeServerStream(_ipcPipeName, PipeDirection.Out); |
| 320 | + // socket used to exchange duplicated socket info with server code |
| 321 | + using Socket ipcServerListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
| 322 | + ipcServerListener.BindToAnonymousPort(IPAddress.Loopback); |
| 323 | + ipcServerListener.Listen(1); |
| 324 | + string ipcPortString = ((IPEndPoint)ipcServerListener.LocalEndPoint).Port.ToString(CultureInfo.InvariantCulture); |
323 | 325 |
|
324 | 326 | if (sameProcess)
|
325 | 327 | {
|
326 |
| - Task handlerCode = Task.Run(() => HandlerServerCode(_ipcPipeName)); |
327 |
| - await RunCommonHostLogic(Environment.ProcessId); |
| 328 | + Task handlerCode = Task.Run(() => HandlerServerCode(ipcPortString)); |
| 329 | + RunCommonHostLogic(Environment.ProcessId); |
328 | 330 | await handlerCode;
|
329 | 331 | }
|
330 | 332 | else
|
331 | 333 | {
|
332 |
| - RemoteInvokeHandle hServerProc = RemoteExecutor.Invoke(HandlerServerCode, _ipcPipeName); |
333 |
| - await RunCommonHostLogic(hServerProc.Process.Id); |
334 |
| - await hServerProc.DisposeAsync(); |
| 334 | + RemoteInvokeHandle hServerProc = RemoteExecutor.Invoke(HandlerServerCode, ipcPortString); |
| 335 | + |
| 336 | + // Since RunCommonHostLogic can throw, we need to make sure the server process is disposed |
| 337 | + try |
| 338 | + { |
| 339 | + RunCommonHostLogic(hServerProc.Process.Id); |
| 340 | + } |
| 341 | + finally |
| 342 | + { |
| 343 | + await hServerProc.DisposeAsync(); |
| 344 | + } |
335 | 345 | }
|
336 | 346 |
|
337 |
| - async Task RunCommonHostLogic(int processId) |
| 347 | + void RunCommonHostLogic(int processId) |
338 | 348 | {
|
339 |
| - await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); |
340 |
| - |
341 |
| - pipeServerStream.WaitForConnection(); |
| 349 | + using Socket ipcServer = ipcServerListener.Accept(); |
| 350 | + ipcServer.NoDelay = true; |
342 | 351 |
|
343 | 352 | // Duplicate the socket:
|
344 | 353 | SocketInformation socketInfo = handlerOriginal.DuplicateAndClose(processId);
|
345 |
| - WriteSocketInfo(pipeServerStream, socketInfo); |
| 354 | + // Send socketInfo to server code |
| 355 | + using var ipcStream = new NetworkStream(ipcServer, false); |
| 356 | + WriteSocketInfo(new NetworkStream(ipcServer), socketInfo); |
346 | 357 |
|
347 | 358 | // Send client data:
|
348 | 359 | client.Send(TestBytes);
|
349 | 360 | }
|
350 | 361 |
|
351 |
| - static async Task<int> HandlerServerCode(string ipcPipeName) |
| 362 | + static async Task<int> HandlerServerCode(string ipcPortString) |
352 | 363 | {
|
353 |
| - await using NamedPipeClientStream pipeClientStream = |
354 |
| - new NamedPipeClientStream(".", ipcPipeName, PipeDirection.In); |
355 |
| - pipeClientStream.Connect(); |
| 364 | + int ipcPort = int.Parse(ipcPortString, CultureInfo.InvariantCulture); |
| 365 | + using Socket ipcClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
| 366 | + ipcClient.NoDelay = true; |
| 367 | + await ipcClient.ConnectAsync(IPAddress.Loopback, ipcPort); |
| 368 | + |
| 369 | + await using var ipcStream = new NetworkStream(ipcClient, true); |
| 370 | + SocketInformation socketInfo = ReadSocketInfo(ipcStream); |
356 | 371 |
|
357 |
| - SocketInformation socketInfo = ReadSocketInfo(pipeClientStream); |
358 | 372 | using Socket handler = new Socket(socketInfo);
|
359 | 373 |
|
360 | 374 | Assert.True(handler.IsBound);
|
|
0 commit comments