diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..36fda64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,256 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+#SoundCloud
+*.sonarqube/
+.sonarlint
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..825c32f
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1 @@
+# Changelog
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..94286c9
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) .NET Foundation and Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..ef0bacf
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/assets/nf-logo.png b/assets/nf-logo.png
new file mode 100644
index 0000000..572c4ff
Binary files /dev/null and b/assets/nf-logo.png differ
diff --git a/assets/readme.txt b/assets/readme.txt
new file mode 100644
index 0000000..ce4b795
--- /dev/null
+++ b/assets/readme.txt
@@ -0,0 +1,21 @@
+ _____ _
+ _ __ __ _ _ __ ___ | ___| __ __ _ _ __ ___ _____ _____ _ __| | __
+ | '_ \ / _` | '_ \ / _ \| |_ | '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
+ | | | | (_| | | | | (_) | _|| | | (_| | | | | | | __/\ V V / (_) | | | <
+ |_| |_|\__,_|_| |_|\___/|_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
+
+===================================================================================
+
+API docs: https://docs.nanoframework.net/api/nanoFramework.System.Net.html
+
+Browse our samples repository: https://github.com/nanoframework/samples
+
+Check our documentation online: https://docs.nanoframework.net/
+
+Join our lively Discord community: https://discord.gg/gCyBu8T
+
+Report issues: https://github.com/nanoframework/Home/issues
+
+Follow us on Twitter: https://twitter.com/nanoframework
+
+Follow our YouTube channel: https://www.youtube.com/c/nanoFramework
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index af93855..fbb463f 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,19 +1,96 @@
-# Starter pipeline
-# Start with a minimal pipeline that you can customize to build and deploy your code.
-# Add steps that build, run tests, deploy, and more:
-# https://aka.ms/yaml
-
trigger:
-- develop
+ branches:
+ include: [main, develop, "release-*" ]
+ paths:
+ exclude: [README.md, LICENSE.md, NuGet.Config, .github_changelog_generator, .gitignore]
+ tags:
+ include: ["v*"]
+
+# PR always trigger build
+pr:
+ autoCancel: true
+
+# add nf-tools repo to resources (for Azure Pipelines templates)
+resources:
+ repositories:
+ - repository: templates
+ 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'
+
+ variables:
+ DOTNET_NOLOGO: true
+ solution: 'nanoFramework.System.Net.Sockets.TcpClient.sln'
+ buildPlatform: 'Any CPU'
+ buildConfiguration: 'Release'
+ nugetPackageName: 'nanoFramework.System.Net.Sockets.TcpClient'
+
+ 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'
+
+##############################
+- 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: ubuntu-latest
+ pool:
+ vmImage: 'windows-2019'
-steps:
-- script: echo Hello, world!
- displayName: 'Run a one-line script'
+ steps:
-- script: |
- echo Add other tasks to build, test, and deploy your project.
- echo See https://aka.ms/yaml
- displayName: 'Run a multi-line script'
+ - 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: ''
diff --git a/nanoframework.System.Net.Sockets.TcpClient.DELIVERABLES.nuspec b/nanoframework.System.Net.Sockets.TcpClient.DELIVERABLES.nuspec
new file mode 100644
index 0000000..4e6610b
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient.DELIVERABLES.nuspec
@@ -0,0 +1,38 @@
+
+
+
+ nanoFramework.System.Net.Sockets.TcpClient.DELIVERABLES
+ $version$
+ nanoFramework.System.Net.Sockets.TcpClient.DELIVERABLES
+ nanoFramework project contributors
+ nanoFramework,dotnetfoundation
+ false
+ LICENSE.md
+
+
+ false
+ https://github.com/nanoframework/System.Net.Sockets.TcpClient
+ https://secure.gravatar.com/avatar/97d0e092247f0716db6d4b47b7d1d1ad
+ images\nf-logo.png
+ Copyright (c) .NET Foundation and Contributors
+ ** DON'T REFERENCE THIS PACKAGE ** Not meant for development. This package includes the deliverable artifacts of the System.Net assembly for .NET nanoFramework. These are for testing purposes and for updating the native code base of the library.
+ nanoFramework.System.Net.Sockets.TcpClient.DELIVERABLES is not meant for development.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient.nuspec b/nanoframework.System.Net.Sockets.TcpClient.nuspec
new file mode 100644
index 0000000..bf706cd
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient.nuspec
@@ -0,0 +1,40 @@
+
+
+
+ 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
new file mode 100644
index 0000000..7309b19
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient.sln
@@ -0,0 +1,27 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+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
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D0F04E3-6AB6-4DE0-88D0-5E30F6F5719B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {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
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1D002B9B-31C6-4E7E-8E6E-667C96B9B295}
+ EndGlobalSection
+EndGlobal
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Properties/AssemblyInfo.cs b/nanoframework.System.Net.Sockets.TcpClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..56a36be
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+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: AssemblyTitle("System.Net.Sockets.TcpClient")]
+[assembly: AssemblyCompany("nanoFramework Contributors")]
+[assembly: AssemblyProduct("System.Net")]
+[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]
+
+////////////////////////////////////////////////////////////////
+// update this whenever the native assembly signature changes //
+[assembly: AssemblyNativeVersion("100.1.0.0")]
+////////////////////////////////////////////////////////////////
+
+// 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)]
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs
new file mode 100644
index 0000000..e42d490
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/LingerOptions.cs
@@ -0,0 +1,39 @@
+//
+// 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.
+//
+
+namespace System.Net.Sockets
+{
+ ///
+ /// Contains information for a socket's linger time, the amount of time it will
+ /// remain after closing if data remains to be sent.
+ ///
+ public class LingerOption
+ {
+ bool _enabled;
+ int _lingerTime;
+
+ ///
+ /// Initializes a new instance of the
+ /// Enable or Disable option.
+ /// Number of seconds to linger after close.
+ public LingerOption(bool enable, int seconds)
+ {
+ Enabled = enable;
+ LingerTime = seconds;
+ }
+
+ ///
+ /// Enables or disables lingering after close.
+ ///
+ public bool Enabled { get => _enabled; set => _enabled = value; }
+
+ ///
+ /// 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
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs
new file mode 100644
index 0000000..c6663ab
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpClient.cs
@@ -0,0 +1,367 @@
+//
+// 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.
+//
+
+namespace System.Net.Sockets
+{
+ public class TcpClient : IDisposable
+ {
+ private Socket _client;
+ private NetworkStream _stream;
+ private bool disposedValue;
+ private AddressFamily _family = AddressFamily.InterNetwork;
+ bool _active;
+
+ ///
+ /// Initializes a new instance of the TcpClient class.
+ ///
+ public TcpClient() : this(AddressFamily.InterNetwork)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the TcpClient class with specified end point
+ ///
+ ///
+ public TcpClient(IPEndPoint localEP)
+ {
+ _family = localEP.AddressFamily;
+ initialize();
+ _client.Bind(localEP);
+ }
+
+ ///
+ /// Initializes a new instance of the TcpClient class with address family.
+ ///
+ ///
+ public TcpClient(AddressFamily family)
+ {
+ _family = family;
+ initialize();
+ }
+
+ ///
+ /// Initializes a new instance of the TcpClient class, Bind and connect to
+ /// host name and port.
+ ///
+ /// Target Host name
+ /// Target port
+ public TcpClient(string hostname, int port)
+ {
+ try
+ {
+ Connect(hostname, port);
+ }
+ catch (Exception ex)
+ {
+ _client?.Close();
+ throw ex;
+ }
+ }
+
+ ///
+ /// Used by TcpListener.Accept()
+ ///
+ ///
+ internal TcpClient(Socket acceptedSocket)
+ {
+ _client = acceptedSocket;
+ _active = true;
+ }
+
+ ///
+ /// Gets or sets the underlying Socket.
+ ///
+ public Socket Client
+ {
+ get => _client;
+ set => _client = value;
+ }
+
+ ///
+ /// Returns the NetworkStream used to send and receive data to remote host.
+ ///
+ /// The underlying NetworkStream.
+ public NetworkStream GetStream()
+ {
+ //if (!_client.Connected)
+ // {
+ // throw new InvalidOperationException("Not connected");
+ // }
+
+ if (_stream == null)
+ {
+ _stream = new NetworkStream(Client, true);
+ }
+ return _stream;
+ }
+
+ ///
+ /// Gets the amount of data that has been received from the network
+ /// and is available to be read.
+ ///
+ public int Available { get => _client.Available; }
+
+
+ ///
+ /// 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;
+ }
+ }
+
+ ///
+ /// Gets or sets the receive time out value of the connection in seconds.
+ ///
+ public int ReceiveTimeout
+ {
+ get
+ {
+ return (int)Client.GetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.ReceiveTimeout);
+ }
+ set
+ {
+ Client.SetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.ReceiveTimeout, value);
+ }
+ }
+
+ ///
+ /// Gets or sets the send time out value of the connection in seconds.
+ ///
+ public int SendTimeout
+ {
+ get
+ {
+ return (int)Client.GetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.SendTimeout);
+ }
+
+ set
+ {
+ Client.SetSocketOption(SocketOptionLevel.Socket,
+ SocketOptionName.SendTimeout, value);
+ }
+ }
+
+ ///
+ /// Gets or sets the value of the connection's linger option
+ ///
+ public LingerOption LingerState
+ {
+ get
+ {
+ int optionValue = (int)Client.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger);
+ return (optionValue < 0)? new LingerOption(false, 0) : new LingerOption(true, optionValue);
+ }
+ set
+ {
+ int optionValue = value.Enabled ? value.LingerTime : -1;
+ Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, optionValue);
+ }
+ }
+
+ ///
+ /// Enables or disables delay when send or receive buffers are full.
+ ///
+ public bool NoDelay
+ {
+ get
+ {
+ return (int)Client.GetSocketOption(SocketOptionLevel.Tcp,
+ SocketOptionName.NoDelay) != 0 ? true : false;
+ }
+ set
+ {
+ Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0);
+ }
+ }
+
+ ///
+ /// Connects the client to a remote TCP host using the specified
+ /// remote network endpoint.
+ ///
+ /// The IPEndPoint to which you intend to connect.
+ public void Connect(IPEndPoint remoteEP)
+ {
+ _client.Connect(remoteEP);
+ _active = true;
+ }
+
+ ///
+ /// Connects the client to a remote TCP host using the specified IP address
+ /// and port number.
+ ///
+ /// The IPAddress of the host to which you intend to connect.
+ /// The port number to which you intend to connect.
+ public void Connect(IPAddress address, int port)
+ {
+ Connect(new IPEndPoint(address, port));
+ }
+
+ ///
+ /// Connects the client to a remote TCP host using the specified IP addresses and port number.
+ ///
+ /// The IPAddress array of the host to which you intend to connect.
+ /// The port number to which you intend to connect.
+ public void Connect(IPAddress[] address, int port)
+ {
+ Connect(new IPEndPoint(address[0], port));
+ }
+
+ ///
+ /// Connects the Client to the specified port on the specified host.
+ ///
+ /// Remote host
+ /// Remote port
+ public void Connect(string hostname, int port)
+ {
+ if (_active)
+ {
+ throw new SocketException(SocketError.IsConnected);
+ }
+
+ IPHostEntry hostEntry = Dns.GetHostEntry(hostname);
+ Exception lastex = null;
+ Socket ipv4Socket = null;
+ Socket ipv6Socket = null;
+
+ try
+ {
+ // Via host name, port constructor ?
+ if (_client == null)
+ {
+ ipv4Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ ipv6Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
+ }
+
+ foreach (IPAddress address in hostEntry.AddressList)
+ {
+ try
+ {
+ if (_client == null)
+ {
+ if (address.AddressFamily == AddressFamily.InterNetwork && ipv4Socket != null)
+ {
+ ipv4Socket.Connect(new IPEndPoint(address, port));
+ _client = ipv4Socket;
+ if (ipv6Socket != null)
+ {
+ ipv6Socket.Close();
+ }
+ }
+ else if (ipv6Socket != null)
+ {
+ ipv6Socket.Connect(new IPEndPoint(address, port));
+ _client = ipv4Socket;
+ if (ipv4Socket != null)
+ {
+ ipv4Socket.Close();
+ }
+ }
+
+ _active = true;
+ break;
+ }
+ else
+ {
+ Connect(new IPEndPoint(address, port));
+ _active = true;
+ break;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex is OutOfMemoryException)
+ {
+ throw;
+ }
+ lastex = ex;
+ }
+ } // for each address
+ }
+ catch (Exception ex)
+ {
+ if (ex is OutOfMemoryException)
+ {
+ throw;
+ }
+ lastex = ex;
+ }
+ finally
+ {
+ // Clean up if it failed
+ if (!_active)
+ {
+ if (ipv6Socket != null)
+ {
+ ipv6Socket.Close();
+ }
+
+ if (ipv4Socket != null)
+ {
+ ipv4Socket.Close();
+ }
+ }
+
+ // Throw exception if connect failed
+ if (lastex != null)
+ {
+ throw lastex;
+ }
+ else
+ {
+ throw new SocketException(SocketError.NotConnected);
+ }
+ }
+ }
+
+ ///
+ /// Disposes this TcpClient instance and
+ /// requests that the underlying TCP connection be closed.
+ ///
+ public void Close()
+ {
+ this.Dispose();
+ }
+
+ private void initialize()
+ {
+ _client = new Socket(_family, SocketType.Stream, ProtocolType.Tcp);
+ _active = false;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _stream?.Dispose();
+ _client?.Close();
+ _client = null;
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ ///
+ /// Dispose TcpClient
+ ///
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs
new file mode 100644
index 0000000..714654c
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/Sockets/TcpListener.cs
@@ -0,0 +1,99 @@
+//
+// 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.
+//
+
+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)
+ {
+ _localEndPoint = localEP;
+ _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
+ }
+
+ ///
+ /// Gets the underlying EndPoint of the current TcpListener.
+ ///
+ public EndPoint LocalEndpoint { get => _localEndPoint; }
+
+ ///
+ /// Gets the underlying network Socket.
+ ///
+ public Socket Server { get => _listenSocket; }
+
+ ///
+ /// Gets a value that indicates whether TcpListener is actively listening
+ /// for client connections.
+ ///
+ protected bool Active { get => _active; }
+
+ ///
+ /// 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)
+ {
+ _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
+ }
+
+ _listenSocket.Bind(_localEndPoint);
+
+ _listenSocket.Listen(backlog);
+
+ _active = true;
+ }
+
+ ///
+ /// Closes the listener.
+ ///
+ public void Stop()
+ {
+ _listenSocket.Close();
+ _listenSocket = null;
+ _active = false;
+ }
+
+ ///
+ /// Accepts a pending connection request.
+ ///
+ /// A TcpClient used to send and receive data.
+ public TcpClient AcceptTcpClient()
+ {
+ TcpClient client = new TcpClient(_listenSocket.Accept());
+
+ return client;
+ }
+
+ ///
+ /// Accepts a pending connection request.
+ ///
+ /// A Socket used to send and receive data.
+ public Socket AcceptSocket()
+ {
+ return _listenSocket.Accept();
+ }
+ }
+}
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
new file mode 100644
index 0000000..90d59c3
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/nanoframework.System.Net.Sockets.TcpClient.nfproj
@@ -0,0 +1,62 @@
+
+
+
+ $(MSBuildExtensionsPath)\nanoFramework\v1.0\
+
+
+
+ Debug
+ AnyCPU
+ {11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 1d0f04e3-6ab6-4de0-88d0-5e30f6f5719b
+ Library
+ Properties
+ 512
+ nanoframework.System.Net.Sockets.TcpClient
+ nanoframework.System.Net.Sockets.TcpClient
+ v1.0
+
+
+
+
+
+
+
+
+
+
+ ..\packages\nanoFramework.CoreLibrary.1.12.0-preview.5\lib\mscorlib.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.Runtime.Events.1.10.0-preview.6\lib\nanoFramework.Runtime.Events.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Text.1.1.3-preview.13\lib\nanoFramework.System.Text.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Net.1.8.0-preview.26\lib\System.Net.dll
+ True
+ True
+
+
+ ..\packages\nanoFramework.System.Threading.1.0.4-preview.14\lib\System.Threading.dll
+ True
+ True
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nanoframework.System.Net.Sockets.TcpClient/packages.config b/nanoframework.System.Net.Sockets.TcpClient/packages.config
new file mode 100644
index 0000000..365ce2e
--- /dev/null
+++ b/nanoframework.System.Net.Sockets.TcpClient/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file