Skip to content

Commit

Permalink
Support for setting port 0 on passive tcp/ip channels
Browse files Browse the repository at this point in the history
  • Loading branch information
RolandKoenig committed Sep 11, 2020
1 parent c90ae0a commit 95d0820
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 10 deletions.
7 changes: 5 additions & 2 deletions MessageCommunicator.Tests/MessageChannelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MessageCommunicator.Tests.Util;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MessageCommunicator.Tests
Expand All @@ -14,20 +15,22 @@ public class MessageChannelTests
[TestMethod]
public async Task Check_SimpleTcpIPConnection()
{
var testingPort = TestUtility.GetFreeTcpPort();

var receiveTaskOnPassiveChannel = new TaskCompletionSource<string>();
var receiveTaskOnActiveChannel = new TaskCompletionSource<string>();

// Define channels
var passiveChannel = new MessageChannel(
new TcpPassiveByteStreamHandlerSettings(IPAddress.Loopback, 40000),
new TcpPassiveByteStreamHandlerSettings(IPAddress.Loopback, testingPort),
new DefaultMessageRecognizerSettings(Encoding.UTF8),
(msg) =>
{
receiveTaskOnPassiveChannel.SetResult(msg.ToString());
msg.ReturnToPool();
});
var activeChannel = new MessageChannel(
new TcpActiveByteStreamHandlerSettings("127.0.0.1", 40000),
new TcpActiveByteStreamHandlerSettings("127.0.0.1", testingPort),
new DefaultMessageRecognizerSettings(Encoding.UTF8),
(msg) =>
{
Expand Down
2 changes: 1 addition & 1 deletion MessageCommunicator.Tests/MessageCommunicator.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
Expand Down
26 changes: 26 additions & 0 deletions MessageCommunicator.Tests/Util/TestUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace MessageCommunicator.Tests.Util
{
internal static class TestUtility
{
public static ushort GetFreeTcpPort()
{
// Simple method do find a free port
// see https://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net

var dummyListener = new TcpListener(IPAddress.Loopback, 0);

dummyListener.Start();
var port = (ushort)((IPEndPoint)dummyListener.LocalEndpoint).Port;
dummyListener.Stop();

return port;
}
}
}
8 changes: 6 additions & 2 deletions MessageCommunicator/MessageChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ public class MessageChannel

public string RemoteEndpointDescription => _byteStreamHandler.RemoteEndpointDescription;

public IMessageReceiveHandler ReceiveHandler { get; }
public IMessageReceiveHandler? ReceiveHandler
{
get => _messageRecognizer.ReceiveHandler;
set => _messageRecognizer.ReceiveHandler = value;
}

public MessageChannel(
ByteStreamHandlerSettings byteStreamHandlerSettings,
MessageRecognizerSettings messageRecognizerSettings,
IMessageReceiveHandler receiveHandler,
IMessageReceiveHandler? receiveHandler = null,
IMessageCommunicatorLogger? logger = null)
{
_byteStreamHandler = byteStreamHandlerSettings.CreateByteStreamHandler();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ private async void RunConnectionMainLoop(int loopId)
CancellationTokenSource? lastCancelTokenSource = null;
TcpListener? tcpListener = null;
var reconnectErrorCount = 0;
var currentListenerPort = this.ListeningPort;
while(loopId == _runningLoopCounter)
{
if (tcpListener == null)
Expand All @@ -136,6 +137,7 @@ private async void RunConnectionMainLoop(int loopId)
}
tcpListener = new TcpListener(this.ListeningIPAddress, this.ListeningPort);
tcpListener.Start();
currentListenerPort = (ushort)((IPEndPoint)tcpListener.LocalEndpoint).Port;

reconnectErrorCount = 0;
_currentListener = tcpListener;
Expand All @@ -144,7 +146,7 @@ private async void RunConnectionMainLoop(int loopId)
{
this.Log(
LoggingMessageType.Info,
StringBuffer.Format("TcpListener created for port {0}", this.ListeningPort));
StringBuffer.Format("TcpListener created for port {0}", currentListenerPort));
}
}
catch (Exception ex)
Expand All @@ -153,7 +155,7 @@ private async void RunConnectionMainLoop(int loopId)
{
this.Log(
LoggingMessageType.Error,
StringBuffer.Format("Error while creating TcpListener for port {0}: {1}", this.ListeningPort, ex.Message),
StringBuffer.Format("Error while creating TcpListener for port {0}: {1}", currentListenerPort, ex.Message),
exception: ex);
}

Expand All @@ -180,7 +182,7 @@ await this.WaitByReconnectWaitTimeAsync(reconnectErrorCount)
this.Log(
LoggingMessageType.Info,
StringBuffer.Format("Listening for incoming connections on port {0}...",
this.ListeningPort));
currentListenerPort));
}

actTcpClient = await tcpListener.AcceptTcpClientAsync()
Expand All @@ -194,7 +196,7 @@ await this.WaitByReconnectWaitTimeAsync(reconnectErrorCount)
LoggingMessageType.Info,
StringBuffer.Format(
"Got new connection on listening port {0}. Connection established between {1} and {2}",
this.ListeningPort, actLocalEndPoint.ToString(), actPartnerEndPoint.ToString()));
currentListenerPort, actLocalEndPoint.ToString(), actPartnerEndPoint.ToString()));
}
}
catch (ObjectDisposedException)
Expand All @@ -210,7 +212,7 @@ await this.WaitByReconnectWaitTimeAsync(reconnectErrorCount)
{
this.Log(
LoggingMessageType.Error,
StringBuffer.Format("Error while listening for incoming connections on port {0}: {1}", this.ListeningPort, ex.Message),
StringBuffer.Format("Error while listening for incoming connections on port {0}: {1}", currentListenerPort, ex.Message),
exception: ex);
}

Expand Down

0 comments on commit 95d0820

Please sign in to comment.