Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Remove Client property from TcpClient and UdpClient#5953

Merged
davidsh merged 1 commit intodotnet:masterfrom
stephentoub:remove_client
Feb 9, 2016
Merged

Remove Client property from TcpClient and UdpClient#5953
davidsh merged 1 commit intodotnet:masterfrom
stephentoub:remove_client

Conversation

@stephentoub
Copy link
Copy Markdown
Member

The property leaks through the abstraction. It's rarely used. And it complicates things on Unix due to exposing the underlying socket instance combined with difficulties with multiple connect calls on a single socket instance.

Until we have good reason to expose it in the contract, we're removing it from the contract before it's stable.

cc: @davidsh, @CIPop, @SidharthNabar, @terrajobst, @weshaggard, @saurabh500
Closes #4968
Closes #5411

The property leaks through the abstraction.  It's rarely used.  And it complicates things on Unix due to exposing the underlying socket instance combined with difficulties with multiple connect calls on a single socket instance.

Until we have good reason to expose it in the contract, we're removing it from the contract before it's stable.
@Maxwe11
Copy link
Copy Markdown
Contributor

Maxwe11 commented Feb 7, 2016

hm...how to get or set ReceiveTimeout/SendTimeout for UdpClient with these changes?

@stephentoub
Copy link
Copy Markdown
Member Author

hm...how to get or set ReceiveTimeout/SendTimeout for UdpClient with these changes?

@CIPop, @davidsh?

@davidsh
Copy link
Copy Markdown
Contributor

davidsh commented Feb 7, 2016

hm...how to get or set ReceiveTimeout/SendTimeout for UdpClient with these changes?

There are many granular properties of a Socket like ReceiveTimeout/SendTimeout that might be useful as direct properties of the TcpClient, UdpClient class. These can all be considered for a future version of the System.Net.Sockets contract. For devs that need this kind of low level control, they can create a Socket directly and set properties on it. The TcpClient, UdpClient class are merely higher level convenience classes.

@saurabh500
Copy link
Copy Markdown
Contributor

@corivera PTAL

@corivera
Copy link
Copy Markdown
Member

corivera commented Feb 8, 2016

Looks good for SqlClient.

@CIPop
Copy link
Copy Markdown

CIPop commented Feb 8, 2016

LGTM

@stephentoub
Copy link
Copy Markdown
Member Author

@davidsh, you can merge this at your convenience when you're ready to handle any internal test issues.

@davidsh
Copy link
Copy Markdown
Contributor

davidsh commented Feb 8, 2016

@stephentoub

you can merge this at your convenience when you're ready to handle any internal test issues.

I've checked in the internal test changes. So, we can merge this when GREEN.

@davidsh
Copy link
Copy Markdown
Contributor

davidsh commented Feb 9, 2016

@stephentoub Thx for doing the PR and driving related downstream changes.

davidsh added a commit that referenced this pull request Feb 9, 2016
Remove Client property from TcpClient and UdpClient
@davidsh davidsh merged commit 1384104 into dotnet:master Feb 9, 2016
@stephentoub stephentoub deleted the remove_client branch February 11, 2016 13:18
@clairernovotny
Copy link
Copy Markdown

Here's a good reason we need this - I cannot currently create a UdpClient that shares a socket correctly. I get an exception with "Only one usage of each socket address (protocol/network address/port) is normally permitted".

The way I handled this before was to create a UdpClient with the default ctor, use the SetSocketOptions for sharing/non-exclusive use, then call Client.Bind(localEndpoint).

It's now impossible to do this because the ExclusiveAddressUse is a property that gets set after UdpClient is constructed.

@clairernovotny
Copy link
Copy Markdown

One option might be to put another ctor arg for exclusive address use so that we can pass that in up-front and prevent the issue?

@Maxwe11
Copy link
Copy Markdown
Contributor

Maxwe11 commented May 15, 2016

Milestone 1.1.0

Does it mean that in 1.0 RTM TcpClient will be shipped with Client property?

@davidsh davidsh modified the milestones: 1.0.0-rtm, 1.1.0 May 15, 2016
@davidsh
Copy link
Copy Markdown
Contributor

davidsh commented May 15, 2016

Does it mean that in 1.0 RTM TcpClient will be shipped with Client property?

No. That was a mistake in Milestone labeling. This PR was merged a while ago.

You can look at the current System.Net.Sockets contract here and see what properties are available on the TcpClient class:
https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/ref/System.Net.Sockets.cs

@clairernovotny
Copy link
Copy Markdown

Without either Client exposed on UdpClient or a way to set exclusive to false before the bind via the ctor, I need to use this really ugly hack along with a rd.xml file to deal with .net native. This is bad just to get it to work :)

static Socket GetSocketFromUdpClient(UdpClient client)
        {
            var mi = GetSocketMember.Value as MethodInfo;
            if (mi != null)
            {
                return (Socket)mi.Invoke(client, null);
            }
            var fi = GetSocketMember.Value as FieldInfo;
            if (fi != null)
            {
                return (Socket)fi.GetValue(client);
            }

            throw new NotSupportedException("Could not locate Socket");
        }

        static readonly Lazy<MemberInfo> GetSocketMember = new Lazy<MemberInfo>(GetSocketMemberImpl);

        static MemberInfo GetSocketMemberImpl()
        {
            // See if there's a client prop
            var pi = typeof(UdpClient).GetRuntimeProperties().FirstOrDefault(p => p.PropertyType == typeof(Socket));
            if (pi != null)
                return pi.GetMethod;

            var mi = typeof(UdpClient).GetRuntimeFields().First(fi => fi.FieldType == typeof(Socket));
            return mi;
        }
    }

@davidsh
Copy link
Copy Markdown
Contributor

davidsh commented May 15, 2016

@onovotny I totally understand your requirements. However, it was not possible to leave the .Client property on the class as returning the raw socket caused problems when one tried to manipulate it later on especially on *Nix platforms.

Please open a new issue (since this PR is merged and closed) and propose an API change. We then all can discuss how to address this requirement. You can reference this PR in your new issue. Thx.

@clairernovotny
Copy link
Copy Markdown

clairernovotny commented May 15, 2016

@stephentoub
Copy link
Copy Markdown
Member Author

However, it was not possible to leave the .Client property on the class as returning the raw socket caused problems when one tried to manipulate it later on especially on *Nix platforms.

To clarify, there were a few concerns with these properties:

  • TcpClient.Client is problematic on Unix. BSD Sockets have undefined behavior after connect on a socket fails, which means we need to play tricks to implement a method like Connect with a DnsEndPoint, as that could actually end up needing to try to connect to multiple sites. We can achieve this by using a new Socket for each attempt, keeping the one that works, but that then conflicts with the Client property, which exposes the actual Socket being used, and potentially before Connect has been used. If we choose to expose this property (which would can certainly look at for post-1.0), we'll need to either make it throw prior to connecting, or prohibit connecting with a DNS endpoint / string host after the Client property has been accessed.
  • To my knowledge, there isn't a similar issue with UdpClient.Client, other than consistency with TcpClient.
  • TcpClient and UdpClient are extremely thin wrappers around a Socket, meant to provide a slightly higher level of abstraction, yet exposing the underlying Socket bleeds through that abstraction.

@clairernovotny
Copy link
Copy Markdown

@stephentoub Thanks for the clarification. While the UdpClient wrapper may be "thin," there's a lot of code in there. The biggest ones are around getting SendAsync/ReceiveAsync to work correctly...there's a lot of gunk in there....and I like the abstraction over using Socket's directly. My concern is really that I cannot do one thing with the UdpClient alone, but that's fixable.

stephentoub added a commit to stephentoub/corefx that referenced this pull request May 17, 2016
stephentoub added a commit to stephentoub/corefx that referenced this pull request May 17, 2016
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Remove Client property from TcpClient and UdpClient

Commit migrated from dotnet/corefx@1384104
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants