public void SocketShouldBeClosedAndBindShouldEndWhenForwardedPortSignalsClosingEvent()
{
_sessionMock.Setup(p => p.IsConnected).Returns(true);
_sessionMock.Setup(p => p.SendMessage(It.IsAny<ChannelOpenMessage>()))
.Callback<Message>(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null,
new MessageEventArgs<ChannelOpenConfirmationMessage>(
new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber))));
_sessionMock.Setup(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()))
.Callback<WaitHandle>(p => p.WaitOne(Session.Infinite));
var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122);
using (var localPortListener = new AsyncSocketListener(localPortEndPoint))
{
localPortListener.Start();
localPortListener.Connected += socket =>
{
var channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize,
_localPacketSize);
channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket);
var closeForwardedPortThread =
new Thread(() =>
{
// sleep for a short period to allow channel to actually start receiving from socket
Thread.Sleep(100);
// raise Closing event on forwarded port
_forwardedPortMock.Raise(p => p.Closing += null, EventArgs.Empty);
});
closeForwardedPortThread.Start();
channel.Bind();
closeForwardedPortThread.Join();
};
var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Connect(localPortEndPoint);
// attempt to receive from socket to verify it was shut down by channel
var buffer = new byte[16];
var bytesReceived = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
Assert.AreEqual(0, bytesReceived);
Assert.IsTrue(client.Connected);
// signal to server that we also shut down the socket at our end
client.Shutdown(SocketShutdown.Send);
}
}