Singularity/Library/PackageCache/com.unity.ide.visualstudio@.../Editor/Messaging/TcpListener.cs
2024-05-06 11:45:45 -07:00

83 lines
1.8 KiB
C#

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
using System;
using System.Net;
using System.Threading;
namespace Microsoft.Unity.VisualStudio.Editor.Messaging
{
internal class TcpListener
{
private const int ListenTimeoutMilliseconds = 5000;
private class State
{
public System.Net.Sockets.TcpListener TcpListener;
public byte[] Buffer;
}
public static int Queue(byte[] buffer)
{
var tcpListener = new System.Net.Sockets.TcpListener(IPAddress.Any, 0);
var state = new State {Buffer = buffer, TcpListener = tcpListener};
try
{
tcpListener.Start();
int port = ((IPEndPoint)tcpListener.LocalEndpoint).Port;
ThreadPool.QueueUserWorkItem(_ =>
{
bool listening = true;
while (listening)
{
var handle = tcpListener.BeginAcceptTcpClient(OnIncomingConnection, state);
listening = handle.AsyncWaitHandle.WaitOne(ListenTimeoutMilliseconds);
}
Cleanup(state);
});
return port;
}
catch (Exception)
{
Cleanup(state);
return -1;
}
}
private static void OnIncomingConnection(IAsyncResult result)
{
var state = (State)result.AsyncState;
try
{
using (var client = state.TcpListener.EndAcceptTcpClient(result))
{
using (var stream = client.GetStream())
{
stream.Write(state.Buffer, 0, state.Buffer.Length);
}
}
}
catch (Exception)
{
// Ignore and cleanup
}
}
private static void Cleanup(State state)
{
state.TcpListener?.Stop();
state.TcpListener = null;
state.Buffer = null;
}
}
}