diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml
new file mode 100644
index 0000000..3d6c0d7
--- /dev/null
+++ b/.github/workflows/update-dependencies.yml
@@ -0,0 +1,32 @@
+# Copyright (c) .NET Foundation and Contributors
+# See LICENSE file in the project root for full license information.
+
+# This workflow will periodically check .NET nanoFramework dependencies and updates them in the repository it's running.
+
+name: Daily update dependencies
+
+on:
+ schedule:
+ # At 00:00 UTC every day.
+ - cron: '00 00 * * *'
+ repository_dispatch:
+ types: update-dependencies
+
+defaults:
+ run:
+ shell: pwsh
+
+jobs:
+ update-dotnet-preview:
+ name: Update .NET nanoFramework dependencies
+ timeout-minutes: 15
+ runs-on: windows-latest
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Update dependencies
+ uses: nanoframework/nanodu@v1
+ with:
+ solutionsToCheck: 'nanoframework.System.Net.Sockets.TcpClient.sln'
diff --git a/.github_changelog_generator b/.github_changelog_generator
new file mode 100644
index 0000000..0813106
--- /dev/null
+++ b/.github_changelog_generator
@@ -0,0 +1,13 @@
+user=nanoframework
+project=System.Net.Sockets.TcpClient
+issues=false
+add_issues_wo_labels=false
+add_pr_wo_labels=false
+add_issues_wo_labels=false
+filter_issues_by_milestone=false
+exclude_labels=Area: Config-and-Build,Area: Infrastructure-and-Organization,reverted
+enhancement_labels=Type: enhancement
+bug_labels=Type: bug
+merge_prefix=**Documentation and other chores:**
+unreleased_label=**Changes available only in 'Preview' NuGet packages:**
+author=false
diff --git a/README.md b/README.md
index f6c70c0..723dc55 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,203 @@
-# System.Net.Sockets.TcpClient
\ No newline at end of file
+
+[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_System.Net.Sockets.TcpClient&metric=alert_status)](https://sonarcloud.io/dashboard?id=nanoframework_System.Net.Sockets.TcpClient) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_System.Net.Sockets.TcpClient&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=nanoframework_System.Net.Sockets.TcpClient) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![NuGet](https://img.shields.io/nuget/dt/nanoFramework.System.Net.Sockets.TcpClient.svg?label=NuGet&style=flat&logo=nuget)](https://www.nuget.org/packages/nanoFramework.System.Net.Sockets.TcpClient/) [![#yourfirstpr](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [![Discord](https://img.shields.io/discord/478725473862549535.svg?logo=discord&logoColor=white&label=Discord&color=7289DA)](https://discord.gg/gCyBu8T)
+
+![nanoFramework logo](https://raw.githubusercontent.com/nanoframework/Home/main/resources/logo/nanoFramework-repo-logo.png)
+
+-----
+
+# System.Net.Sockets.TcpClient
+
+This API implements the TcpListener and TcpClient classes with a pattern similar to the official .NET equivalent. [System.NET.Sockets.TcpClient](https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.TcpClient).
+
+These are wrapper classes for the Socket when using TCP connections.
+The nanoframework implementation of TcpClient doesn't include the asynchronous methods and the Connected property.
+
+
+## Build status
+
+| Component | Build Status | NuGet Package |
+|:-|---|---|
+| nanoFramework.System.Net.Sockets.TcpClient | [![Build Status](https://dev.azure.com/nanoframework/System.Net.Sockets.TcpClient/_apis/build/status/System.Net.Sockets.TcpClient?branchName=main)](https://dev.azure.com/nanoframework/System.Net.Sockets.TcpClient/_build/latest?definitionId=91&branchName=main) | [![NuGet](https://img.shields.io/nuget/v/nanoFramework.System.Net.Sockets.TcpClient.svg?label=NuGet&style=flat&logo=nuget)](https://www.nuget.org/packages/nanoFramework.System.Net.Sockets.TcpClient/) |
+| nanoFramework.System.Net.Sockets.TcpClient (preview) | [![Build Status](https://dev.azure.com/nanoframework/System.Net.Sockets.TcpClient/_apis/build/status/System.Net.Sockets.TcpClient?branchName=develop)](https://dev.azure.com/nanoframework/System.Net.Sockets.TcpClient/_build/latest?definitionId=91&branchName=develop) | [![NuGet](https://img.shields.io/nuget/vpre/nanoFramework.System.Net.Sockets.TcpClient.svg?label=NuGet&style=flat&logo=nuget)](https://www.nuget.org/packages/nanoFramework.System.Net.Sockets.TcpClient/) |
+
+## Usage
+
+**Important:** Obviously this requires a working network connection. Please check the examples with the Network Helpers on how to connect to a network. For example see the [Networking sample pack](https://github.com/nanoframework/Samples/tree/main/samples/Networking)
+
+The `TcpListener` class provides simple methods for creating a listening socket to accept incoming TCP connections and the `TcpClient` provides methods for connecting and communicating on a TCP connection.
+
+### Samples
+
+Samples for `TcpListener` and `TcpClient` are present in the [nanoFramework Sample repository](https://github.com/nanoframework/Samples).
+
+### Listening for incoming connections
+
+The following codes shows how to set up a Listening socket and to accept connections as a TcpClient on the 1234 port.
+
+```csharp
+TcpListener listener = new TcpListener(IPAddress.Any, 1234);
+
+// Start listening for incoming connections
+listener.Start();
+while (true)
+{
+ try
+ {
+ // Wait for incoming connections
+ TcpClient client = listener.AcceptTcpClient();
+
+ NetworkStream stream = client.GetStream();
+
+ Byte[] bytes = new Byte[256];
+ int i;
+
+ // Wait for incoming data and echo back
+ while((i = stream.Read(bytes, 0, bytes.Length))!=0)
+ {
+ // Do something with data ?
+
+ stream.Write(bytes, 0, i);
+ }
+
+ // Shutdown connection
+ client.Close();
+ }
+ catch(Exception ex)
+ {
+ Debug.WriteLine($"Exception:-{ex.Message}");
+ }
+}
+```
+
+If you want to handle more then one simultaneous connection then a separate worker thread can be started.
+
+```csharp
+TcpListener listener = new TcpListener(IPAddress.Any, 1234);
+
+// Start listening for incoming connections with backlog
+listener.Start(2);
+
+while (true)
+{
+ try
+ {
+ // Wait for incoming connections
+ TcpClient client = listener.AcceptTcpClient();
+
+ // Start thread to handle connection
+ Thread worker = new Thread(() => WorkerThread(client));
+ worker.Start();
+ }
+ catch(Exception ex)
+ {
+ Debug.WriteLine($"Exception:-{ex.Message}");
+ }
+}
+```
+
+Worker Thread for handling the TcpClient connection for TcpListener example.
+
+```csharp
+private static void WorkerThread(TcpClient client)
+{
+ try
+ {
+ NetworkStream stream = client.GetStream();
+
+ Byte[] bytes = new Byte[256];
+ int i;
+
+ // Loop reading data until connection closed
+ while((i = stream.Read(bytes, 0, bytes.Length))!=0)
+ {
+ // Do something with data ?
+
+ // Write back received data bytes to stream
+ stream.Write(bytes, 0, i);
+ }
+ }
+ catch(Exception ex)
+ {
+ Debug.WriteLine($"Exception:-{ex.Message}");
+ }
+ finally
+ {
+ // Shutdown connection
+ client.Close();
+ }
+}
+```
+
+### TcpClient
+
+The TcpClient can also be used to initiate a connection passing in the hostname/port or IPEndPoint.
+Maybe connecting to another nanoFramework device which is listening for connections.
+
+```csharp
+TcpClient client = new TcpClient()
+
+try
+{
+ client.Connect(hostname, port)
+
+ NetworkStream stream = client.GetStream();
+
+ // Write / Read data on stream
+
+ // for example Write 'ABC' and wait for response
+ byte[] writeData = new byte[] { 0x41, 0x42, 0x43 };
+ stream.Write(writeData, 0, writeData.Length);
+
+ // Read reply and close
+ byte[] buffer = new byte[1024];
+ int bytesRead = stream.Read(buffer, 0, buffer.Length);
+
+ // Process read data ?
+}
+catch(SocketException sx)
+{
+ Console.WriteLine($"Socket error:{sx.ErrorCode} exception:{sx.Message}");
+}
+finally
+{
+ client.Close();
+}
+```
+
+For secure connections a `SslStream` can be used.
+
+```csharp
+client.Connect(HostName, 443);
+
+// Create SSlStream from underlying SOcket
+SslStream stream = new SslStream(client.Client);
+
+// Don't verify Server certificate for this sample code
+stream.SslVerification = SslVerification.NoVerification;
+stream.AuthenticateAsClient(HostName, SslProtocols.Tls12);
+
+// stream.Write() or stream.Read()
+```
+
+## Feedback and documentation
+
+For documentation, providing feedback, issues and finding out how to contribute please refer to the [Home repo](https://github.com/nanoframework/Home).
+
+Join our Discord community [here](https://discord.gg/gCyBu8T).
+
+## Credits
+
+The list of contributors to this project can be found at [CONTRIBUTORS](https://github.com/nanoframework/Home/blob/main/CONTRIBUTORS.md).
+
+## License
+
+The **nanoFramework** Class Libraries are licensed under the [MIT license](LICENSE.md).
+
+## Code of Conduct
+
+This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behaviour in our community.
+For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
+
+### .NET Foundation
+
+This project is supported by the [.NET Foundation](https://dotnetfoundation.org).
\ No newline at end of file
diff --git a/Tests/ConnectionTests.cs b/Tests/ConnectionTests.cs
new file mode 100644
index 0000000..6e615da
--- /dev/null
+++ b/Tests/ConnectionTests.cs
@@ -0,0 +1,257 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+//
+
+using nanoFramework.TestFramework;
+using System;
+using System.Diagnostics;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace NFUnitTests
+{
+ [TestClass]
+ public class ConnectionTests
+ {
+ const int TESTPORT = 1234;
+ static byte[] _testData = new byte[256];
+
+ [Setup]
+ public void Initialize()
+ {
+ // Remove this line to run hardware tests
+ Assert.SkipTest("No Network");
+
+ Debug.WriteLine("TcpListener.TcpClient connection Tests initialized.");
+
+ // Init test data
+ for (int i = 0; i < _testData.Length; i++)
+ {
+ _testData[i] = (byte)i;
+ }
+ }
+
+ [TestMethod]
+ public void ListenAndConnect()
+ {
+ const int MaxConnections = 4;
+
+ bool testRunning = true;
+ int workerID = 1;
+ int connectionAccepted = 0;
+
+ Thread[] workers = new Thread[MaxConnections];
+
+ // Create listener on Loop back address
+ TcpListener listener = CreateListener();
+
+ listener.Start(4);
+
+ // Start some Threads to connect to Listener and Send/Receive data
+ for (int sndCount = 0; sndCount < MaxConnections; sndCount++)
+ {
+ Thread Sender1 = new Thread(() => SenderThread(100 + workerID++));
+ Sender1.Start();
+ }
+
+ while (testRunning)
+ {
+ // All connections accepted, break accept loop
+ if (connectionAccepted >= MaxConnections)
+ {
+ break;
+ }
+
+ try
+ {
+ TcpClient client = listener.AcceptTcpClient();
+
+ workers[connectionAccepted] = new Thread(() => WorkerThread(client, workerID++));
+ workers[connectionAccepted].Start();
+
+ connectionAccepted++;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"Exception:-{ex.Message}");
+ Thread.Sleep(500);
+ }
+ }
+
+ listener.Stop();
+ Debug.WriteLine($"listener stopped");
+
+ Debug.WriteLine($"Waiting for Workers to end");
+
+ bool WorkersRunning = true;
+ while (WorkersRunning)
+ {
+ // Wait for all Worker threads to close
+ WorkersRunning = false;
+ foreach (Thread thd in workers)
+ {
+ if (thd.IsAlive)
+ {
+ WorkersRunning = true;
+ break;
+ }
+ }
+
+ Thread.Sleep(10);
+ }
+
+ Debug.WriteLine($"All workers ended");
+ }
+
+ public static void SenderThread(int workerID)
+ {
+ // IPV4 address
+ IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, TESTPORT);
+
+ TcpClient sender = new TcpClient();
+
+ sender.Connect(endPoint);
+
+ NetworkStream stream = sender.GetStream();
+
+ for (int count = 1; count < 20; count++)
+ {
+ int length = count * 2;
+
+ // Write header
+ stream.WriteByte(0xfc);
+ stream.WriteByte((byte)(length & 0xff)); // Low length
+ stream.WriteByte((byte)((length >> 8) & 0xff)); // High length
+
+ byte[] buffer = new byte[length];
+
+ // fill buffer with test data
+ Array.Copy(_testData, count, buffer, 0, length);
+
+ stream.Write(buffer, 0, length);
+
+ Array.Clear(buffer, 0, length);
+
+ int sync = stream.ReadByte();
+ Assert.True(sync == 0xfc, $"{workerID} count={count} read sync != 0xfc => {sync}");
+ int lenL = stream.ReadByte();
+ int lenH = stream.ReadByte();
+ int dataLength = (lenH << 8) + lenL;
+ Assert.True(dataLength == length, $"{workerID} Sender rx invalid length {dataLength} should be {length}");
+
+ int readBytes = stream.Read(buffer, 0, length);
+ Assert.True(readBytes == length, $"{workerID} Read bytes:{readBytes} <> requested length:{length}");
+
+ // Validate buffer
+ for (int i = 0; i < length; i++)
+ {
+ Assert.False(buffer[i] != _testData[i + count], $"Received data not same as send, position:{i} {buffer[i]}!={_testData[i + count]}");
+ }
+
+ Debug.WriteLine($"{workerID}: Send/Receive count:{count} complete");
+ }
+
+ stream.Close();
+ sender.Dispose();
+ }
+
+ ///
+ /// Thread to echo back data received
+ /// Data in format 0xFC, length:uint16, data bytes .......
+ ///
+ /// TcpClient
+ /// ID for logging
+ public static void WorkerThread(TcpClient client, int workerID)
+ {
+ Debug.WriteLine($" {workerID}:Client connected to {client.Client.RemoteEndPoint.ToString()}");
+
+ NetworkStream stream = client.GetStream();
+
+ // Set RX time outs on stream
+ stream.ReadTimeout = 10000;
+
+ // Netstream.Read will return straight away if there is no data to read
+ while (true)
+ {
+ try
+ {
+ // Wait for first byte
+ // This will sit on Read until 1 byte of data available giving time to other threads
+ int syncbyte = stream.ReadByte();
+ if (syncbyte == -1)
+ {
+ Debug.WriteLine($"{workerID}:Connection closed");
+ break;
+ }
+
+ Assert.True(syncbyte == 0xfc, $"{workerID}:Sync byte != FC => {syncbyte}");
+
+ int lenL = stream.ReadByte();
+ int lenH = stream.ReadByte();
+ int dataLength = (lenH << 8) + lenL;
+ Assert.True(dataLength <= 512, $"{workerID}:Invalid length {dataLength}");
+
+ byte[] buffer = new byte[dataLength];
+
+ // Then read the rest of data in loop
+ int bufferPos = 0;
+ int bytesToRead = 0;
+
+ while (bytesToRead < dataLength)
+ {
+ int dataAv = client.Available;
+ if (dataAv > 0)
+ {
+ int bytesRead = stream.Read(buffer, bufferPos, dataAv);
+ bufferPos += bytesRead;
+ bytesToRead += bytesRead;
+ }
+ else
+ {
+ Thread.Sleep(0);
+ }
+ }
+
+ Assert.True(bytesToRead == dataLength, $"{workerID}:Data read != availableInvalid length {dataLength}");
+
+ stream.WriteByte(0xfc);
+ stream.WriteByte((byte)(dataLength & 0xff)); // Low length
+ stream.WriteByte((byte)((dataLength >> 8) & 0xff)); // High length
+
+ // Echo data back
+ stream.Write(buffer, 0, dataLength);
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"{workerID}:Worker exception {ex.Message}");
+ break;
+ }
+ } // while
+
+ client.Close();
+ Debug.WriteLine($"{workerID}:Worker closed");
+ }
+
+ ///
+ /// Create a TcpListener and check
+ ///
+ /// TcpListener
+ public TcpListener CreateListener()
+ {
+ TcpListener listener = new TcpListener(IPAddress.Loopback, TESTPORT);
+ Assert.NotNull(listener);
+
+ Debug.WriteLine("TcpListener created.");
+
+ Assert.Equal(((IPEndPoint)listener.LocalEndpoint).Port, TESTPORT, "Wrong port on Listener");
+ Assert.Equal((int)((IPEndPoint)listener.LocalEndpoint).AddressFamily, (int)AddressFamily.InterNetwork, "Wrong address family");
+ Assert.True(((IPEndPoint)listener.LocalEndpoint).Address == IPAddress.Loopback, "Wrong IP address");
+
+ return listener;
+ }
+ }
+}
diff --git a/Tests/Properties/AssemblyInfo.cs b/Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a3735af
--- /dev/null
+++ b/Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright (c) 2021 nanoFramework contributors")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tests/Tests.nfproj b/Tests/Tests.nfproj
new file mode 100644
index 0000000..9754daf
--- /dev/null
+++ b/Tests/Tests.nfproj
@@ -0,0 +1,97 @@
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ a0df7a0b-8dcd-4cfa-a29f-49f0c2400a07
+ Library
+ Properties
+ 512
+ NFUnitTests
+ NFUnitTest
+ False
+ true
+ UnitTest
+ v1.0
+
+
+
+ $(MSBuildProjectDirectory)\nano.runsettings
+
+
+
+
+
+
+
+
+ ..\packages\nanoFramework.CoreLibrary.1.12.0-preview.9\lib\mscorlib.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.Runtime.Events.1.10.0-preview.8\lib\nanoFramework.Runtime.Events.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Text.1.1.3-preview.15\lib\nanoFramework.System.Text.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.TestFramework.1.0.178\lib\nanoFramework.TestFramework.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.TestFramework.1.0.178\lib\nanoFramework.UnitTestLauncher.exe
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.IO.Streams.1.0.0-preview.12\lib\System.IO.Streams.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Net.1.8.0-preview.29\lib\System.Net.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Threading.1.0.4-preview.16\lib\System.Threading.dll
+ True
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Update the Import path in nfproj to the correct nanoFramework.TestFramework NuGet package folder.
+
+
+
+
\ No newline at end of file
diff --git a/Tests/UnitTestListener.cs b/Tests/UnitTestListener.cs
new file mode 100644
index 0000000..b73f94b
--- /dev/null
+++ b/Tests/UnitTestListener.cs
@@ -0,0 +1,75 @@
+//
+// Copyright (c) .NET Foundation and Contributors
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+using nanoFramework.TestFramework;
+using System;
+using System.Diagnostics;
+using System.Net;
+using System.Net.Sockets;
+
+namespace NFUnitTests
+{
+ [TestClass]
+ public class TestTcpListener
+ {
+ private const int TESTPORT = 1234;
+
+ [Setup]
+ public void Initialize()
+ {
+ // Remove this line to run hardware tests
+ Assert.SkipTest("No Network");
+
+ Debug.WriteLine("TcpListener Tests initialized.");
+ }
+
+ [TestMethod]
+ public void CreateAndStart()
+ {
+ Debug.WriteLine("CreateAndStart.");
+
+ TcpListener listener = CreateListener();
+
+ listener.Start(1);
+
+ // Get underlying socket
+ Socket listenSocket = listener.Server;
+ Assert.NotNull(listenSocket, "Listen socket null");
+
+ listener.Stop();
+
+ listener = null;
+ }
+
+ [TestMethod]
+ public void StateExceptionChecks()
+ {
+ TcpListener listener = CreateListener();
+
+ Assert.Throws(typeof(InvalidOperationException), () => { listener.Stop(); }, "No exception when stopping and not started");
+
+ listener.Start(1);
+
+ Assert.Throws(typeof(InvalidOperationException), () => { listener.Start(1); }, "No exception when starting and already started");
+
+ listener.Stop();
+ }
+
+ public TcpListener CreateListener()
+ {
+ TcpListener listener = new TcpListener(IPAddress.Loopback, TESTPORT);
+ Assert.NotNull(listener);
+
+ Debug.WriteLine("TcpListener created.");
+
+ Assert.Equal(((IPEndPoint)listener.LocalEndpoint).Port, TESTPORT, "Wrong port on Listener");
+ Assert.Equal((int)((IPEndPoint)listener.LocalEndpoint).AddressFamily, (int)AddressFamily.InterNetwork, "Wrong address family");
+ Assert.True(((IPEndPoint)listener.LocalEndpoint).Address == IPAddress.Loopback, "Wrong IP address");
+
+ return listener;
+ }
+ }
+}
diff --git a/Tests/nano.runsettings b/Tests/nano.runsettings
new file mode 100644
index 0000000..fa881e3
--- /dev/null
+++ b/Tests/nano.runsettings
@@ -0,0 +1,14 @@
+
+
+
+
+ 1
+ .\TestResults
+ 120000
+ Framework40
+
+
+ None
+ False
+
+
\ No newline at end of file
diff --git a/Tests/packages.config b/Tests/packages.config
new file mode 100644
index 0000000..ed5cafb
--- /dev/null
+++ b/Tests/packages.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index fbb463f..744da23 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,10 +1,27 @@
+# Copyright (c) .NET Foundation and Contributors
+# See LICENSE file in the project root for full license information.
+
trigger:
branches:
- include: [main, develop, "release-*" ]
+ include:
+ - main
+ - develop
+ - release-*
paths:
- exclude: [README.md, LICENSE.md, NuGet.Config, .github_changelog_generator, .gitignore]
+ exclude:
+ - .github_changelog_generator
+ - .gitignore
+ - CHANGELOG.md
+ - CODE_OF_CONDUCT.md
+ - LICENSE.md
+ - README.md
+ - NuGet.Config
+ - assets/*
+ - config/*
+ - .github/*
tags:
- include: ["v*"]
+ include:
+ - v*
# PR always trigger build
pr:
@@ -17,80 +34,29 @@ resources:
type: github
name: nanoframework/nf-tools
endpoint: nanoframework
-
-jobs:
-##############################
-- job: Build_Library
- condition: or( eq(variables['UPDATE_DEPENDENTS'], 'false'), eq(variables['StartReleaseCandidate'], 'true') )
-
- pool:
- vmImage: 'windows-2019'
+pool:
+ vmImage: 'windows-latest'
- variables:
- DOTNET_NOLOGO: true
- solution: 'nanoFramework.System.Net.Sockets.TcpClient.sln'
- buildPlatform: 'Any CPU'
- buildConfiguration: 'Release'
- nugetPackageName: 'nanoFramework.System.Net.Sockets.TcpClient'
+variables:
+ DOTNET_NOLOGO: true
+ solution: 'nanoFramework.System.Net.Sockets.TcpClient.sln'
+ buildPlatform: 'Any CPU'
+ buildConfiguration: 'Release'
+ nugetPackageName: 'nanoFramework.System.Net.Sockets.TcpClient'
- steps:
+steps:
- # step from template @ nf-tools repo
- # all build, update and publish steps
- - template: azure-pipelines-templates/class-lib-build.yml@templates
- parameters:
- sonarCloudProject: 'nanoframework_lib-nanoFramework.System.Net.Sockets.TcpClient'
- runUnitTests: false
- unitTestRunsettings: '$(System.DefaultWorkingDirectory)\Tests\SocketTests\nano.runsettings'
+# step from template @ nf-tools repo
+# build steps only
+- template: azure-pipelines-templates/class-lib-build.yml@templates
+ parameters:
+ sonarCloudProject: 'nanoframework_System.Net.Sockets.TcpClient'
-##############################
-- job: Update_Dependents
- condition: or( and( succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['StartReleaseCandidate'], 'false') ), and( succeeded(), contains(variables['getCommitMessage.COMMIT_MESSAGE'], '***UPDATE_DEPENDENTS***'), eq(variables['StartReleaseCandidate'], 'false') ), eq(variables['UPDATE_DEPENDENTS'], 'true') )
-
- dependsOn:
- - Build_Library
-
- pool:
- vmImage: 'windows-2019'
-
- variables:
- DOTNET_NOLOGO: true
-
- steps:
-
- - checkout: none
-
- # update dependents
- - template: azure-pipelines-templates/update-dependents.yml@templates
- parameters:
- repositoriesToUpdate: |
- System.Net.Http
- System.Net.WebSockets
- System.Device.WiFi
- nanoFramework.m2mqtt
- nanoFramework.Azure.Devices
-
-##################################
-# report build failure to Discord
-- job: Report_Build_Failure
- condition: or( failed('Build_Library'), failed('Update_Dependents'))
-
- dependsOn:
- - Build_Library
- - Update_Dependents
-
- pool:
- vmImage: 'windows-2019'
-
- steps:
-
- - checkout: self
-
- # step from template @ nf-tools repo
- # report error
- - template: azure-pipelines-templates/discord-webhook-task.yml@templates
- parameters:
- status: 'failure'
- webhookUrl: '$(DiscordWebhook)'
- message: ''
+# step from template @ nf-tools repo
+# report error
+- template: azure-pipelines-templates/discord-webhook-task.yml@templates
+ parameters:
+ status: 'failure'
+ webhookUrl: '$(DiscordWebhook)'
+ message: ''
\ No newline at end of file
diff --git a/config/SignClient.json b/config/SignClient.json
new file mode 100644
index 0000000..482177d
--- /dev/null
+++ b/config/SignClient.json
@@ -0,0 +1,14 @@
+{
+ "SignClient": {
+ "AzureAd": {
+ "AADInstance": "https://login.microsoftonline.com/",
+ "ClientId": "c248d68a-ba6f-4aa9-8a68-71fe872063f8",
+ "TenantId": "16076fdc-fcc1-4a15-b1ca-32c9a255900e"
+ },
+ "Service": {
+ "Url": "https://codesign.dotnetfoundation.org/",
+ "ResourceId": "https://SignService/3c30251f-36f3-490b-a955-520addb85001"
+ }
+ }
+ }
+
\ No newline at end of file
diff --git a/config/filelist.txt b/config/filelist.txt
new file mode 100644
index 0000000..ca7fde1
--- /dev/null
+++ b/config/filelist.txt
@@ -0,0 +1 @@
+**/nanoFramework.System.Net.Sockets.TcpClient.*
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient.nuspec b/nanoframework.System.Net.Sockets.TcpClient.nuspec
index bf706cd..7d78d23 100644
--- a/nanoframework.System.Net.Sockets.TcpClient.nuspec
+++ b/nanoframework.System.Net.Sockets.TcpClient.nuspec
@@ -1,40 +1,44 @@
-
- nanoframework.System.Net.Sockets.TcpClient
- $version$
- nanoframework.System.Net.Sockets.TcpClient
- nanoFramework project contributors
- nanoFramework,dotnetfoundation
- false
- LICENSE.md
-
-
- docs\README.md
- false
- https://github.com/nanoframework/System.Net.Sockets.TcpClient
- images\nf-logo.png
-
- Copyright (c) .NET Foundation and Contributors
- This package includes the .NET nanoFramework System.Net assembly for .NET nanoFramework C# projects.
-This package requires a target with System.Net v$nativeVersion$ (checksum $checksum$).
- nanoFramework C# csharp netmf netnf nanoFramework.System.Net
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ nanoframework.System.Net.Sockets.TcpClient
+ $version$
+ nanoframework.System.Net.Sockets.TcpClient
+ nanoFramework project contributors
+ nanoFramework,dotnetfoundation
+ false
+ LICENSE.md
+
+
+ docs\README.md
+ false
+ https://github.com/nanoframework/System.Net.Sockets.TcpClient
+ images\nf-logo.png
+
+ Copyright (c) .NET Foundation and Contributors
+
+ This package includes the .NET nanoFramework System.Net assembly for .NET nanoFramework C# projects.
+ This package requires a target with System.Net v$nativeVersion$ (checksum $checksum$).
+
+ nanoFramework C# csharp netmf netnf nanoFramework.System.Net
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient.sln b/nanoframework.System.Net.Sockets.TcpClient.sln
index 7309b19..7ed83e1 100644
--- a/nanoframework.System.Net.Sockets.TcpClient.sln
+++ b/nanoframework.System.Net.Sockets.TcpClient.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.32002.261
MinimumVisualStudioVersion = 10.0.40219.1
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "nanoframework.System.Net.Sockets.TcpClient", "nanoframework.System.Net.Sockets.TcpClient\nanoframework.System.Net.Sockets.TcpClient.nfproj", "{1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}"
EndProject
+Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Tests", "Tests\Tests.nfproj", "{A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -17,6 +19,12 @@ Global
{1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Release|Any CPU.Build.0 = Release|Any CPU
{1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0DF7A0B-8DCD-4CFA-A29F-49F0C2400A07}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs
index e42d490..f0e2753 100644
--- a/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs
@@ -12,13 +12,10 @@ namespace System.Net.Sockets
///
public class LingerOption
{
- bool _enabled;
- int _lingerTime;
-
///
- /// Initializes a new instance of the
///
- /// Enable or Disable option.
+ /// Enable or disable option.
/// Number of seconds to linger after close.
public LingerOption(bool enable, int seconds)
{
@@ -29,11 +26,11 @@ namespace System.Net.Sockets
///
/// Enables or disables lingering after close.
///
- public bool Enabled { get => _enabled; set => _enabled = value; }
+ public bool Enabled { get; set; }
///
/// The amount of time, in seconds, to remain connected after a close.
///
- public int LingerTime { get => _lingerTime; set => _lingerTime = value; }
- }
-}
\ No newline at end of file
+ public int LingerTime { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs
index c6663ab..77d333c 100644
--- a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs
@@ -6,13 +6,15 @@
namespace System.Net.Sockets
{
+ ///
+ /// Provides client connections for TCP network services.
+ ///
public class TcpClient : IDisposable
{
- private Socket _client;
private NetworkStream _stream;
- private bool disposedValue;
- private AddressFamily _family = AddressFamily.InterNetwork;
- bool _active;
+ private bool _disposed;
+ private readonly AddressFamily _family = AddressFamily.InterNetwork;
+ private bool _active;
///
/// Initializes a new instance of the TcpClient class.
@@ -29,7 +31,7 @@ namespace System.Net.Sockets
{
_family = localEP.AddressFamily;
initialize();
- _client.Bind(localEP);
+ Client.Bind(localEP);
}
///
@@ -54,10 +56,10 @@ namespace System.Net.Sockets
{
Connect(hostname, port);
}
- catch (Exception ex)
+ catch (Exception)
{
- _client?.Close();
- throw ex;
+ Client?.Close();
+ throw;
}
}
@@ -67,18 +69,14 @@ namespace System.Net.Sockets
///
internal TcpClient(Socket acceptedSocket)
{
- _client = acceptedSocket;
+ Client = acceptedSocket;
_active = true;
}
///
/// Gets or sets the underlying Socket.
///
- public Socket Client
- {
- get => _client;
- set => _client = value;
- }
+ public Socket Client { get; set; }
///
/// Returns the NetworkStream used to send and receive data to remote host.
@@ -86,15 +84,11 @@ namespace System.Net.Sockets
/// The underlying NetworkStream.
public NetworkStream GetStream()
{
- //if (!_client.Connected)
- // {
- // throw new InvalidOperationException("Not connected");
- // }
-
if (_stream == null)
{
_stream = new NetworkStream(Client, true);
}
+
return _stream;
}
@@ -102,20 +96,30 @@ namespace System.Net.Sockets
/// Gets the amount of data that has been received from the network
/// and is available to be read.
///
- public int Available { get => _client.Available; }
+ public int Available { get => Client.Available; }
+ private byte[] MilliSecsToTimeval(int millSecs)
+ {
+ byte[] timeval = new byte[8];
+ int secs = millSecs / 1000;
+ int usecs = (millSecs % 1000) * 1000;
- ///
- /// Return connection status of underlying socket.
- ///
- public bool Connected
- {
- get
- {
- // We should be returning the _client.Connected state but that's not available
- // so for the moment just return active state
- return _active;
- }
+ byte[] bsecs = BitConverter.GetBytes(secs);
+ byte[] busecs = BitConverter.GetBytes(usecs);
+ Array.Copy(bsecs, timeval, 4);
+ Array.Copy(busecs, 0, timeval, 4, 4);
+
+ return timeval;
+ }
+
+ private int TimevalToMilliSecs(byte[] timeval)
+ {
+ // Bytes 0 - 3 secs
+ // Bytes 4 - 7 usecs
+ int secs = BitConverter.ToInt32(timeval, 0);
+ int usecs = BitConverter.ToInt32(timeval, 4);
+
+ return (secs * 1000) + (usecs / 1000);
}
///
@@ -125,13 +129,20 @@ namespace System.Net.Sockets
{
get
{
- return (int)Client.GetSocketOption(SocketOptionLevel.Socket,
- SocketOptionName.ReceiveTimeout);
+ byte[] timeval = new byte[8];
+
+ Client.GetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.ReceiveTimeout, timeval);
+
+ return TimevalToMilliSecs(timeval);
}
+
set
{
+ byte[] timeval = MilliSecsToTimeval(value);
+
Client.SetSocketOption(SocketOptionLevel.Socket,
- SocketOptionName.ReceiveTimeout, value);
+ SocketOptionName.ReceiveTimeout, timeval);
}
}
@@ -142,14 +153,20 @@ namespace System.Net.Sockets
{
get
{
- return (int)Client.GetSocketOption(SocketOptionLevel.Socket,
- SocketOptionName.SendTimeout);
+ byte[] timeval = new byte[8];
+
+ Client.GetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.SendTimeout, timeval);
+
+ return TimevalToMilliSecs(timeval);
}
set
{
+ byte[] timeval = MilliSecsToTimeval(value);
+
Client.SetSocketOption(SocketOptionLevel.Socket,
- SocketOptionName.SendTimeout, value);
+ SocketOptionName.SendTimeout, timeval);
}
}
@@ -161,8 +178,9 @@ namespace System.Net.Sockets
get
{
int optionValue = (int)Client.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger);
- return (optionValue < 0)? new LingerOption(false, 0) : new LingerOption(true, optionValue);
+ return (optionValue < 0) ? new LingerOption(false, 0) : new LingerOption(true, optionValue);
}
+
set
{
int optionValue = value.Enabled ? value.LingerTime : -1;
@@ -171,15 +189,17 @@ namespace System.Net.Sockets
}
///
- /// Enables or disables delay when send or receive buffers are full.
+ /// Enables or disables delay when send or receive buffers are not full. (Nagle)
+ /// True if delay is disabled.
///
public bool NoDelay
{
get
{
return (int)Client.GetSocketOption(SocketOptionLevel.Tcp,
- SocketOptionName.NoDelay) != 0 ? true : false;
+ SocketOptionName.NoDelay) != 0;
}
+
set
{
Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0);
@@ -193,7 +213,7 @@ namespace System.Net.Sockets
/// The IPEndPoint to which you intend to connect.
public void Connect(IPEndPoint remoteEP)
{
- _client.Connect(remoteEP);
+ Client.Connect(remoteEP);
_active = true;
}
@@ -215,7 +235,24 @@ namespace System.Net.Sockets
/// The port number to which you intend to connect.
public void Connect(IPAddress[] address, int port)
{
- Connect(new IPEndPoint(address[0], port));
+ foreach (IPAddress ipadr in address)
+ {
+ try
+ {
+ Connect(new IPEndPoint(ipadr, port));
+ break;
+ }
+ catch (Exception)
+ {
+ // Ignore exception as we will throw NotConnected exception
+ // if not connected, _active not set.
+ }
+ }
+
+ if (!_active)
+ {
+ throw new SocketException(SocketError.NotConnected);
+ }
}
///
@@ -238,7 +275,7 @@ namespace System.Net.Sockets
try
{
// Via host name, port constructor ?
- if (_client == null)
+ if (Client == null)
{
ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
@@ -248,12 +285,12 @@ namespace System.Net.Sockets
{
try
{
- if (_client == null)
+ if (Client == null)
{
if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null)
{
ipv4Socket.Connect(new IPEndPoint(address, port));
- _client = ipv4Socket;
+ Client = ipv4Socket;
if (ipv6Socket != null)
{
ipv6Socket.Close();
@@ -262,7 +299,7 @@ namespace System.Net.Sockets
else if (ipv6Socket != null)
{
ipv6Socket.Connect(new IPEndPoint(address, port));
- _client = ipv4Socket;
+ Client = ipv4Socket;
if (ipv4Socket != null)
{
ipv4Socket.Close();
@@ -285,6 +322,7 @@ namespace System.Net.Sockets
{
throw;
}
+
lastex = ex;
}
} // for each address
@@ -295,6 +333,7 @@ namespace System.Net.Sockets
{
throw;
}
+
lastex = ex;
}
finally
@@ -311,8 +350,12 @@ namespace System.Net.Sockets
{
ipv4Socket.Close();
}
- }
+ }
+ }
+
+ if (!_active)
+ {
// Throw exception if connect failed
if (lastex != null)
{
@@ -336,22 +379,22 @@ namespace System.Net.Sockets
private void initialize()
{
- _client = new Socket(_family, SocketType.Stream, ProtocolType.Tcp);
+ Client = new Socket(_family, SocketType.Stream, ProtocolType.Tcp);
_active = false;
}
protected virtual void Dispose(bool disposing)
{
- if (!disposedValue)
+ if (!_disposed)
{
if (disposing)
{
_stream?.Dispose();
- _client?.Close();
- _client = null;
+ Client?.Close();
+ Client = null;
}
- disposedValue = true;
+ _disposed = true;
}
}
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs
index 714654c..569cbbe 100644
--- a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs
@@ -6,94 +6,103 @@
namespace System.Net.Sockets
{
- public class TcpListener
- {
- EndPoint _localEndPoint;
- Socket _listenSocket;
- bool _active = false;
-
- ///
- /// Initializes a new instance of the TcpListener class that listens for incoming connection attempts on the specified local IP address and port number.
- ///
- /// An IPAddress that represents the local IP address.
- /// The port on which to listen for incoming connection attempts.
- public TcpListener(IPAddress localaddr, int port) : this(new IPEndPoint(localaddr, port))
- {
- }
-
- ///
- /// Initializes a new instance of the TcpListener class that listens for incoming connection
- /// attempts with the specified endpoint.
- ///
- /// An IPEndPoint that represents the local endpoint to which to bind the listener Socket.
- public TcpListener(IPEndPoint localEP)
+ ///
+ /// Listens for connections from TCP network clients.
+ ///
+ public class TcpListener
+ {
+ ///
+ /// Initializes a new instance of the TcpListener class that listens for incoming connection attempts on the specified local IP address and port number.
+ ///
+ /// An IPAddress that represents the local IP address.
+ /// The port on which to listen for incoming connection attempts.
+ public TcpListener(IPAddress localaddr, int port) : this(new IPEndPoint(localaddr, port))
{
- _localEndPoint = localEP;
- _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
- }
+ }
- ///
- /// Gets the underlying EndPoint of the current TcpListener.
- ///
- public EndPoint LocalEndpoint { get => _localEndPoint; }
+ ///
+ /// Initializes a new instance of the TcpListener class that listens for incoming connection
+ /// attempts with the specified endpoint.
+ ///
+ /// An IPEndPoint that represents the local endpoint to which to bind the listener Socket.
+ public TcpListener(IPEndPoint localEP)
+ {
+ LocalEndpoint = localEP;
+ Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
+ }
- ///
- /// Gets the underlying network Socket.
- ///
- public Socket Server { get => _listenSocket; }
+ ///
+ /// Gets the underlying EndPoint of the current TcpListener.
+ ///
+ public EndPoint LocalEndpoint { get; }
- ///
- /// Gets a value that indicates whether TcpListener is actively listening
- /// for client connections.
- ///
- protected bool Active { get => _active; }
+ ///
+ /// Gets the underlying network Socket.
+ ///
+ public Socket Server { get; private set; }
- ///
- /// Starts listening for incoming connection requests with a maximum number of pending connection.
- ///
- /// The maximum length of the pending connections queue.
- public void Start(int backlog)
- {
- if (_listenSocket == null)
+ ///
+ /// Gets a value that indicates whether TcpListener is actively listening
+ /// for client connections.
+ ///
+ protected bool Active { get; private set; }
+
+ ///
+ /// Starts listening for incoming connection requests with a maximum number of pending connection.
+ ///
+ /// The maximum length of the pending connections queue.
+ public void Start(int backlog)
+ {
+ if (Active)
{
- _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
- }
+ throw new InvalidOperationException();
+ }
- _listenSocket.Bind(_localEndPoint);
+ if (Server == null)
+ {
+ Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
+ }
- _listenSocket.Listen(backlog);
+ Server.Bind(LocalEndpoint);
- _active = true;
- }
+ Server.Listen(backlog);
- ///
- /// Closes the listener.
- ///
- public void Stop()
+ Active = true;
+ }
+
+ ///
+ /// Closes the listener.
+ ///
+ public void Stop()
{
- _listenSocket.Close();
- _listenSocket = null;
- _active = false;
- }
+ if (Active)
+ {
+ throw new InvalidOperationException();
+ }
- ///
- /// Accepts a pending connection request.
- ///
- /// A TcpClient used to send and receive data.
- public TcpClient AcceptTcpClient()
- {
- TcpClient client = new TcpClient(_listenSocket.Accept());
+ Server.Close();
+ Server = null;
+ Active = false;
+ }
- return client;
- }
-
- ///
- /// Accepts a pending connection request.
- ///
- /// A Socket used to send and receive data.
- public Socket AcceptSocket()
+ ///
+ /// Accepts a pending connection request.
+ ///
+ /// A TcpClient used to send and receive data.
+ public TcpClient AcceptTcpClient()
{
- return _listenSocket.Accept();
- }
- }
+ TcpClient client = new TcpClient(Server.Accept());
+
+ return client;
+ }
+
+ ///
+ /// Accepts a pending connection request.
+ ///
+ /// A Socket used to send and receive data.
+ public Socket AcceptSocket()
+ {
+ return Server.Accept();
+ }
+ }
}
diff --git a/nanoframework.System.Net.Sockets.TcpClient/key.snk b/nanoframework.System.Net.Sockets.TcpClient/key.snk
new file mode 100644
index 0000000..67c9bb0
Binary files /dev/null and b/nanoframework.System.Net.Sockets.TcpClient/key.snk differ
diff --git a/nanoframework.System.Net.Sockets.TcpClient/nanoframework.System.Net.Sockets.TcpClient.nfproj b/nanoframework.System.Net.Sockets.TcpClient/nanoframework.System.Net.Sockets.TcpClient.nfproj
index 90d59c3..227eeb7 100644
--- a/nanoframework.System.Net.Sockets.TcpClient/nanoframework.System.Net.Sockets.TcpClient.nfproj
+++ b/nanoframework.System.Net.Sockets.TcpClient/nanoframework.System.Net.Sockets.TcpClient.nfproj
@@ -16,6 +16,15 @@
nanoframework.System.Net.Sockets.TcpClient
v1.0
+
+ true
+
+
+ key.snk
+
+
+ false
+
@@ -25,27 +34,32 @@
- ..\packages\nanoFramework.CoreLibrary.1.12.0-preview.5\lib\mscorlib.dll
+ ..\packages\nanoFramework.CoreLibrary.1.12.0-preview.9\lib\mscorlib.dll
True
True
- ..\packages\nanoFramework.Runtime.Events.1.10.0-preview.6\lib\nanoFramework.Runtime.Events.dll
+ ..\packages\nanoFramework.Runtime.Events.1.10.0-preview.8\lib\nanoFramework.Runtime.Events.dll
True
True
- ..\packages\nanoFramework.System.Text.1.1.3-preview.13\lib\nanoFramework.System.Text.dll
+ ..\packages\nanoFramework.System.Text.1.1.3-preview.15\lib\nanoFramework.System.Text.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.IO.Streams.1.0.0-preview.12\lib\System.IO.Streams.dll
True
True
- ..\packages\nanoFramework.System.Net.1.8.0-preview.26\lib\System.Net.dll
+ ..\packages\nanoFramework.System.Net.1.8.0-preview.29\lib\System.Net.dll
True
True
- ..\packages\nanoFramework.System.Threading.1.0.4-preview.14\lib\System.Threading.dll
+ ..\packages\nanoFramework.System.Threading.1.0.4-preview.16\lib\System.Threading.dll
True
True
@@ -59,4 +73,11 @@
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
+
+
+
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient/packages.config b/nanoframework.System.Net.Sockets.TcpClient/packages.config
index 365ce2e..eedc150 100644
--- a/nanoframework.System.Net.Sockets.TcpClient/packages.config
+++ b/nanoframework.System.Net.Sockets.TcpClient/packages.config
@@ -1,8 +1,10 @@
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/version.json b/version.json
new file mode 100644
index 0000000..5711497
--- /dev/null
+++ b/version.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "1.0.0-preview.{height}",
+ "assemblyVersion": {
+ "precision": "revision"
+ },
+ "semVer1NumericIdentifierPadding": 3,
+ "nuGetPackageVersion": {
+ "semVer": 2.0
+ },
+ "publicReleaseRefSpec": [
+ "^refs/heads/main$",
+ "^refs/heads/v\\d+(?:\\.\\d+)?$"
+ ],
+ "cloudBuild": {
+ "setAllVariables": true
+ },
+ "release": {
+ "branchName": "release-v{version}",
+ "versionIncrement": "build",
+ "firstUnstableTag": "preview"
+ }
+}