83 lines
1.8 KiB
C#
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|