System.Net.Sockets problem

  • Thread starter Thread starter JDavis
  • Start date Start date
J

JDavis

I am using System.Net.Sockets to connect a client socket to a server that
requires three inputs when I connect: host, port and an identification
number that identifies the person connecting.

None of the overloads for either the Connect or BeginConnect methods takes
that many inputs (basically they take host and port only).

Would it be best to create a new class that derives from the base class
System.Net.Sockets and implement a new method? And if so, any tips on what
my new method should look like?

Thanks very much for any ideas.
 
JDavis said:
I am using System.Net.Sockets to connect a client socket to a server that
requires three inputs when I connect: host, port and an identification
number that identifies the person connecting.

You don't say, but I assume you are using TCP/IP. If so, the network
protocol itself only supports an IP address and port number for
identifying an endpoint.

First thing is that you have not been very clear about what even the
"host" and "port" items indicate for the connection. Are you specifying
the server's IP address and port number? Or is the client supposedly
providing its own IP address and port number to the server?

Your other comments seem to imply that these are actually the server IP
address and port, but if that's the case then it's not really true that
the server "requires three inputs". The server itself only requires the
identification number. It's the local socket API that requires the
other two (so that it can contact the server for you).

As far as the identification number goes, that must be part of your
application-level protocol. Since the protocol presumably requires a
variety of other things implemented as well to support it, then the
place for that identification number is wherever you implement the rest
of the application protocol.
None of the overloads for either the Connect or BeginConnect methods takes
that many inputs (basically they take host and port only).

That's because the network protocol doesn't know anything about your
application protocol. You tell the network API the server's IP address
and port number. It then connects you to the server, and the rest is up
to you.
Would it be best to create a new class that derives from the base class
System.Net.Sockets and implement a new method? And if so, any tips on what
my new method should look like?

IMHO, you need a class that implements the application protocol. This
class would _contain_ a socket, but would not inherit the Socket class.
The socket is a necessary part of the implementation of the protocol,
but the application protocol itself does not derive from the socket, so
the class shouldn't inherit the socket.

Note that this is a conceptual opinion. You could easily view the
situation differently, asserting that since your application protocol is
in fact implemented on top of the underlying network protocol, that your
application protocol class should inherit the underlying network API
class. IMHO, the main problem with this is that your application
protocol is unlikely to need, or even want, to expose the underlying
network API.

From the application's point of view, it should not care at all that
the application protocol is implemented on top of a network protocol, so
inheriting the class is not only not useful, it prevents your
application protocol class from fully encapsulating and hiding the
underlying i/o implementation. By doing this, your application protocol
can be made to work on any number of i/o APIs, not just the Socket
class. In that case, you would make a base abstract class that at least
describes the required public methods, if not implements some of the
behavior based on some basic assumed behavior for the i/o API, and then
you can create i/o-API-specific classes inheriting the base application
protocol class.

You may in fact never have a need to do any of this latter stuff. But
IMHO the potential for that illustrates why I feel that the application
protocol isn't really inherited from the network protocol.

Pete
 
Would it be best to create a new class that derives from the base class
System.Net.Sockets and implement a new method?

I assume you mean System.Net.Sockets.Socket here. But for inspiration,
there is already something in the framework which does what you
consider: System.Net.Sockets.TcpClient is what Peter suggests, a class
that implements the application protocol (in a way) and contains a
Socket. You could look at TcpClient and see if that resembles what you
want to do. (Or, if you're always going to use TCP/IP, you might want
to use a TcpClient in your application instead of a Socket.)
 
UL-Tomten said:
I assume you mean System.Net.Sockets.Socket here. But for inspiration,
there is already something in the framework which does what you
consider: System.Net.Sockets.TcpClient is what Peter suggests, a class
that implements the application protocol (in a way) and contains a
Socket.

I don't agree that TcpClient implements an application protocol. I
realize you wrote "in a way", and that does mitigate the disparity
somewhat. But TcpClient is really just a specialized Socket, that
handles only the TCP network protocol. It knows nothing about any
higher-level protocols.

And even TcpClient doesn't inherit Socket, even though it is about as
close as you can get to a class that's a Socket without being a Socket. :)

There _are_ application-protocol-specific classes, and they also don't
inherit the Socket class. See the WebRequest class and its inheritors
for examples of that.

I guess what I'm getting at is that I'm not convinced that inheriting
the Socket class is a good design. I can't remember...did I mention
that yet? :)

Pete
 
I don't agree that TcpClient implements an application protocol. I
realize you wrote "in a way", [...]

But you couldn't leave it at that, could you. No, you had to go all
OSI on me! I was trying not to confuse the original poster, but now
you've unleashed hell. =]
And even TcpClient doesn't inherit Socket, even though it is about as
close as you can get to a class that's a Socket without being a Socket. :)

I like to think of TcpClient as a managed socket, and Socket as a very
thin Winsock2 wrapper. This tends to lead to very few surprises. The
error handling is IMHO the thing about Socket that's the least
managed, since the general approach is to wrap the Winsock2 error in a
SocketException. In an analogy: if the File class just threw a
FileException with ERROR_INVALID_TARGET_HANDLE in it instead of
throwing a specialized Exception, I think people would be
disappointed.
There _are_ application-protocol-specific classes, and they also don't
inherit the Socket class. See the WebRequest class and its inheritors
for examples of that.

Bet you didn't know that HttpWebRequest is one of the largest classes
in the framework!
I guess what I'm getting at is that I'm not convinced that inheriting
the Socket class is a good design.

I agree with what you wrote above: only inherit from Socket if you're
writing a specialized type of Socket. I tend to use extension methods
to make Sockets smarter. Also, I think the Socket class is a bit too
unpredictable to serve as a good base class. Look at the Dispose()
method (which is the only virtual or protected member), for example. I
wonder if it isn't a good candidate for sealing...
 
Thanks for the suggestions. I was wrong about the requirement of three
inputs -- the server can only take two, as you've said, because TCP/IP only
takes two. The third element is sent after a successful connection.
 
UL-Tomten said:
But you couldn't leave it at that, could you. No, you had to go all
OSI on me!
"OSI"?

I was trying not to confuse the original poster, but now
you've unleashed hell. =]

Um. Hell? Okay. If you say so.
I like to think of TcpClient as a managed socket, and Socket as a very
thin Winsock2 wrapper.

I guess that's fair enough. However, I still find Socket to have some
important characteristics of a managed class. Specifically, it wraps
the use of i/o completion ports in a very simple, easy-to-use way.

You are right about the error handling being different, but at least
there's the SocketError enumeration. That is, in other "unmanaged"
areas of .NET, you pretty much just have to copy and paste values from
the unmanaged Windows header files. For example, various window message
codes that you might use in WndProc.

And of course, TcpClient doesn't completely hide you from the
error-handling of the Socket class anyway. It can still throw a
SocketException, which just takes you right back to the Socket class.
This tends to lead to very few surprises. The
error handling is IMHO the thing about Socket that's the least
managed, since the general approach is to wrap the Winsock2 error in a
SocketException. In an analogy: if the File class just threw a
FileException with ERROR_INVALID_TARGET_HANDLE in it instead of
throwing a specialized Exception, I think people would be
disappointed.

Maybe. Though, I note there's about twice as many different errors a
Socket can throw via SocketException than there are various file
i/o-related exceptions. That'd be a lot of exceptions defined in the
namespace.

Also, in the case of the Socket class where the handling for specific
errors may be different, but is in fact shared between some specific
errors, it's simpler to write a single exception clause that inspects
the SocketError value, rather than creating multiple clauses that all
just call a common error-handling method.

I can't say that I've found myself disappointed with the design of the
Socket class, error-handling aspects or otherwise. I find it to be a
very nice enhancement to the underlying Winsock API.

Pete
 
JDavis said:
Thanks for the suggestions. I was wrong about the requirement of three
inputs -- the server can only take two, as you've said, because TCP/IP only
takes two. The third element is sent after a successful connection.

Well, as I said, it's not the server that "takes two". You use those
two locally, so that you can contact the server. The third element is
what the server "takes", and you can only give it once you've
successfully connected to the server.

I suppose you might find the above pointless semantic quibbling, but
IMHO it's a fundamental part of how the network API works. It might
seem like a minor difference in meaning now, but many times subtle bugs
are created by subtle misunderstandings. Having a precise view of what
is actually happening is important to using the API correctly.

Pete
 

Open Systems Interconnection Basic Reference Model. It defines 7
network layers, where IP is below TCP is below HTTP, etc. I envy your
buzzword-free existence.
I can't say that I've found myself disappointed with the design of the
Socket class, error-handling aspects or otherwise. I find it to be a
very nice enhancement to the underlying Winsock API.

I agree, which is the very reason I don't think the Socket class is
anywhere near as mature as other classes. Specifically, I think the
managed socket API has done too little to overcome the problems
connected to leaky abstractions[1]. For me, exposing all the
SocketErrors is a good thing, because I'm somewhat used to them. But
for the beginner?

1: http://www.joelonsoftware.com/articles/LeakyAbstractions.html
 
Back
Top