I am trying to understand programming with sockets on a more detailed level rather than just with the API callings. I have fair understanding of C# WCF and socket programming using WinSocks in C++. Now I have 2 main questions:
Does WCF use sockets internally for the communication in all cases. In other words is WCF a wrapper around sockets and is built upon them?
Does all kind of network based communication use sockets at the end for sending/receiving data, which is something mandated by the OSI model?
A little detailed explanation will be better than just a Yes/No answer.
(With acknowledgement to the other SO users who agreed to reopen this question).
As an opening remark, remember that it's 2019 2020 and WCF is obsolete and I'm personally glad to see it gone, and I strongly recommend against using WCF for any new projects and I advise people to transition away from WCF as soon as possible.
Now, in response to your question (bold emphasis mine):
Does WCF use sockets internally for the communication in all cases. In other words is WCF a wrapper around sockets and is built upon them?
Strictly speaking, no (but in a practical sense, for inter-machine transport, yes).
WCF is a .NET platform that is concerned with "message processing". WCF tries to abstract away the underlying details of message transport (but it does so horribly, and so no-one should use it today), so it is entirely possible to build a WCF application that achieves inter-machine and inter-network communication without ever using Windows' Winsock, or whatever "Socket"-esque API is available for a given computing platform.
Now, while ostensibly WCF is all about abstraction, in practice WCF was geared around SOAP messages (and SOAP is horrible too, but that's another discussion), and SOAP primarily uses HTTP as a message transport - and HTTP primarily uses TCP/IP, and almost every single TCP/IP application on Microsoft Windows will be using the Winsock API somewhere in the process' communication stack. (It can be argued that HTTP applications on Windows will use http.sys which performs HTTP request/response processing in kernel-mode, which necessarily means bypassing Windows' user-mode Winsock API and instead http.sys uses "Winsock Kernel" which is its own thing).
In the above paragraph, note the use of the word "primarily" (as opposed to "exclusively" or "always") - because:
WCF doesn't have to use SOAP, it can use other messaging models/protocols/paradigms like net.tcp (which itself is more like a "binary SOAP") or even REST (though REST support came late in WCF's lifespan and it's a total pain to configure correctly, YMMV).
SOAP doesn't have to use HTTP, it can use other transports like SMTP. And WCF expressly supports other SOAP's other main transports like SMTP and FTP.
While HTTP is effectively tied to TCP/IP and Winsock is the only real way a user-mode application will use TCP/IP, other transports like SMTP don't have to use TCP/IP (at least, not in the way you think - see my footnote).
And of course, throughout all of this - user-mode applications are always free to use a different Networking Programming Interface besides Winsock or BSD sockets (for example, Windows' named-pipes present a streaming IPC interface just like how TCP behaves - or the vendor of a network-interface-card could have its own exclusively networking API which is somehow simply better than the Sockets API (similar to how GPU vendors in the mid-1990s were pushing their own APIs (Glide, PowerVR, Rendition, etc) until they all ended-up having to support Direct3D and OpenGL (and who uses Metal? hah).
And while WCF isn't exactly designed with testability in mind, it is still possible to host and run WCF applications inside an integration-testing environment where the actual message transport is just a thin proxy object, or a faked or mocked implementation - so Sockets are completely avoided there as well.
But in practice - in Win32, networking is accomplished using Winsock (Microsoft's implementation of the BSD Sockets API) so if you're using WCF to communicate between machines then I can say with 99% certainty that eventually your messages will pass-through Winsock.
Footnote: Regarding using WCF with SMTP without using Sockets: Many SMTP e-mail servers, including Microsoft Exchange Server, support "pickup directories" - which are filesystem directories actively monitored by the e-mail server, which detects when a new file has been added to the folder and reads each file as an SMTP envelope and processes it the same way as though it was an SMTP envelope received by the server's SMTP service endpoint - if a SOAP-in-SMTP message were to be "dropped" inside the pickup directory and it was destined for a recipient local to the pickup directory's e-mail service, then that message will not pass through Winsock at all either.
Related
I have an old non-WCF Windows Service that creates a TCPClient to connect to a non-WCF TCP Server. I can't change the server app at all. It attempts to create a 2 threads, one for reading and processing messages from the Server, and one for reading from an MSMQ queue, processing, and then for sending to the TCP Server. Unfortunately, there are problems, and sometimes if there is a network disconnection I will get two instances of either the read or write threads. The threads share the same TCPClient connection.
Was hoping to switch my service to WCF, hosted by a Windows Service. I know I could use MSMQIntegration binding for a send method, but I am not sure how I could bind to a shared TCP connection. netTCPBinding seems to also be limited to WCF to WCF connections. Does anyone have suggestions on how to proceed?
This is theoretically possible with WCF's extensibility, but you would have to write a custom endpoint, a custom message formatter, and the fifty other classes. I'd recommend implementing the TCP service separately.
WCF Extensibility is best considered when you are dealing with a SOAP-like service which uses XML-like messages over a standard endpoint (transport). When you are "pretty close" to that, you can usually patch over the differences. When you are using none of that, WCF becomes a hindrance rather than a timesaver. For example, I would use WCF extensibility if:
I had a SOAP service which needed to run over SMTP or some other odd transport (custom endpoint)
I had a custom xml format that runs over a standard endpoint (I*MessageInspector)
I had a custom format which can be readily converted to XML running over a standard endpoint (custom message encoder)
I would not use WCF for:
Any format which does not convert readily to XML
Any format which does not readily identify the Action / target method
REST services (despite internal support - look at MVC Web API)
Anything requiring transport of large binary blobs (unless MTOM covers it)
Services where more than one of the built-in components have to be replaced
WCF library is the library that allows developers to communicate between WCF and non-WCF services in protocol agnostic way. Service developers using WCF don't need to known the details of protocol used between these services because these intricacies are hidden in WCF bindings. So the service developers have just to configure their client or server endpoints/bindings/behaviors correctly and these endpoints/bindings/behaviors do all the labor.
But WCF in not an universal platform to communicate with 'anything'. For instance NetTcpBinding uses TCP sockets to communicate. TCP protocol allows to create a pipeline between both parties but when this pipeline is established, TCP doesn't specify or mandate what content should be send through this pipeline. It can be some standardized protocol like HTTP, or proprietary custom protocol invented by SW developer that has never been published. There are hundreds maybe thousands of custom protocols that can flow through TCP including protocols like Modbus via TCP or IEC104. These 2 protocols for instance were specially designed to be tiny to communicate with the embedded devices and can't be used as the protocols for exchanging universal messages between Web services.
NetTcpBinding sends through TCP pipeline its own completely independent protocol designed by MS to provide efficient communication with WCF services build upon NetTcpBinding. It can't be used to communicate with your custom service using some unknown protocol with different (unknown) data serialization, timing, security, data exchange patterns, etc..
So the only viable option here is to use 'raw sockets' - classes like Socket or TcpClient to communicate with your proprietary service. But at first you must know what protocol your TCP Server is using. Maybe it's some standardized protocol like SOAP or HTTP or completely independent proprietary protocol that has never been published or documented.
And even though WCF has many extensibility options that allows developers to extend WCF library, these extensibility options are meant to be used when you want to allow WCF to communicate via other transport protocol (UDP, serial line, shared network path) or to add some new features to WCF bindings like new security option some extended transaction support or logging. But extending WCF to communicate with some non-WCF proprietary service (using some home-made protocol) would be inefficient (maybe impossible) and over-complicated.
So if your non-WCF service isn't using protocol that very close (virtually the same) as the protocol NetTcpBinding is using then WCF is not an option here. Use Socket or TcpClient classes.
I've never had to do IPC on Windows before. I'm developing a pair of programs, a standard GUI/CLI app, and a windows service. The app has to tell the service what to do. So, assuming the communication is local only, what would be the best communication method for these two processes?
By best I mean more robust and less error prone, not the best performance nor the easiest to code.
Note I'm asking about what to use, a standard TCP socket, named pipes, or some other means of communication only.
IPC in .Net can be achieved using:
WCF
using named pipes requires .Net 3.0 and above.
Code example
The WCF class NetNamedPipeBinding can be used for interprocess communication on the same machine. The MSDN documentaion for this class includes a code sample covering this scenario http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx
Remoting
The original IPC framework released with .Net 1.0. I believe remoting is no longer being actively developed, and you are encouraged to use WCF instead
Code example
Inter-process communication via Remoting - uses a tcp channel
Resources
GenuineChannels, sell a remoting toolkit that includes a Shared Memory Channel. http://www.genuinechannels.com/Index.aspx
Ingo Rammer, wrote the definitive .Net remoting book, Advanced .NET Remoting, Second Edition
Win32 RPC using csharptest-net RpcLibrary
I came across a project recently that has wrapped the Win32 RPC library and created a .net class library that can be used for local and remote RPC
Project home page: http://csharptest.net/projects/rpclibrary/
MSDN references:
How rpc works: http://technet.microsoft.com/en-us/library/cc738291(v=ws.10).aspx
RPC functions: http://msdn.microsoft.com/en-us/library/aa378623(v=VS.85).aspx
Also has a google protocol buffers rpc client that runs on top of the library: https://code.google.com/p/protobuf-csharp-rpc/
WM_COPYDATA
For completeness it's also possible to use the WIN32 method with the WM_COPYDATA message. I've used this method before in .Net 1.1 to create a single instance application opening multiple files from windows explorer.
Resources
MSDN - WM_COPYDATA
Code example
PInvoke.net declaration
Sockets
Using a custom protocol (harder)
For local only, we have had success using Named Pipes. Avoids the overhead of TCP, and is pretty much (at least for .NET) as efficient as you can get while also having a decent API to work with.
Since you are limited to .Net 2.0 WCF is perhaps not an option. You could use .Net remoting with shared memory as the underlying communication mechanism between app domains on the same machine. Using this approach you can easily put your processes on different machines and replace the shared memory protocol with a network protocol.
The standard method of communicating with a windows service is to use service control codes. Windows services can receive codes from 0 to 255. 0-127 is reserved for system. 128 to 255 can be used for custom commands.
If you need to send complex objects to the service use database, xml, file, tcp, http etc. Other than that for sending control commands like reload configuration, process items etc this control codes should be used.
There are additional functionalities available such as querying the service. See Windows service documentation and api.
http://arcanecode.com/2007/05/30/windows-services-in-c-sending-commands-to-your-windows-service-part-7/
Your best bet is to use WCF. You will be able to create a service host in the windows service and expose a well defined interface that the GUI application can consume. WCF will let you communicate via named pipes if you choose, or you can choose any other communication protocal like TCP, HTTP, etc. Using WCF you get great tool support and lots of available information.
I'd like to add to this discussion. Please rebuke me if this is way out there - but couldn't a semaphore (or multiple semaphores) be used for rudimentary communication?
I'm currently learning the basics of WCF , and I stumbled upon the following flow :
Meaning that my client needs to speak with a Proxy class , that communicates with the WCF server .
Why can't I (the client) speak directly with the server , instead of using a third party for the job ?
There's nothing stopping you from not using a c# WCF proxy client to communicate with a WCF service, you could always do without and use say raw TCP/HTTP/pipes/MSMQ. However, doing so generally requires alot of effort and time - time during which most people would generally prefer to spend reading the Hitchhiker's Guide to the Galaxy.
Heavy?
WCF proxies are actually not as heavy as it may sound. They're not really "3rd party" either. There're generally nothing more than light-weight classes compiled in with your application. They don't run say out-of-process as may happen in certain COM scenarios.
The notion of a "3rd party" proxy is not unique to WCF. DCOM also has the concept of proxies, but unlike WCF, they are created for you behind the scenes and are unable to be avoided. Sometimes, as mentioned, they even run in another process! WCF, or should I say SOAP services (generally), differs from DCOM because the client proxies are not required. They just make the use case of using a SOAP service easier. Luckily that part of Windows had to make way for a hyperspace bypass, so the use of DCOM in contemporary applications is essentially no more.
The client proxies help your life by:
encapsulating and serializing the method call into a request message (usually SOAP)
abstracting you from the underlying transport when the call to the service is made transmitting the request message from the prior step. i.e. using TCP; HTTP; MSMQ etc APIs. Want your TCP WCF service to accept a local named pipe client? Easy just change the config file, no code change is generally required!
deserializing the response message into a user friendly c# object(s)
handles all the tedious; complex and necessary security for you in the form of security tokens; cookies et al
When is WCF not WCF?
So going back to your question again:
Why can't a client speak directly (!) with a WCF server , instead of using a proxy class that does that?
...when you consider that WCF unifies all the comms APIs into a single API; abstracts and encapsulates a SOAP service, then we could say that all WCF clients by definition use WCF proxies to talk to a WCF service.
As soon as a client explicitly uses raw TCP; MSMQ; HTTP; named pipes APIs in code, it essentially stops being a WCF client (remember WCF is all about unified comms) and instead becomes a SOAP client (or perhaps REST). I would even argue that using the IRequestChannel interface with its Request() method, introduces a messaging concept that was not apparent with standard WCF client proxy code (even if it still abstracts transports from the user). By way of comparison, if I add a MSMQ binding to my pure WCF-client-proxy-using-app's WCF config, my code generally doesn't take on an asynchronous messaging model typically associated with MSMQ. That's the nice thing about WCF.
Of course the server, written in WCF, will be quite content in the knowledge that it considers itself "WCF" regardless of whether clients think it is WCF; SOAP or some scary XML payload being shot over TCP in much the same way as the deity that is Pluto, considers itself to be a planet regardless of what classification system happens to be in fashion at the time.
If you want to treat the service as a WCF service - use WCF client proxies (because we generally don't care about the underlying SOAP message being sent about)
If you want to talk to the service directly without proxies, then you should think about the remote service as a SOAP service and so arm yourself with not only low-level comms APIs but also how to construct and process SOAP messages
Are non-Proxy Approaches Recommended?
Whilst you could do without the proxy, it is not recommended because if you wanted to change security, transports, max message lengths, protocols such as JSON, add async methods, you would be required to perform a great deal of code changes to your non-proxy-using-app compared to the proxy approach.
Like the starship Heart of Gold, WCF is "Glad to be of service" but understands should you desire manual helm control.
Gratuitous references to Douglas Adam's fine radio play; TV mini-series and book The Hitchhiker's Guide to the Galaxy. Why not press the Don't Panic button and read it today?
So I'm pretty new to WCF myself, but I'm pretty sure the proxy class is there to give you the types you need your code to reference. When you make a WCF call, you are serializing data, so you need a class to define that. The proxy allows you to write code against it, acting like you know what its methods and data contracts are, but when the code is actually executed, a WCF call is made and serialized messages are sent back and forth.
I am currently working in socket based technology where my client(C++) and Server(.Net) uses
socket based communication to send and receive data,but now I am looking to replace my existing socket server with WCF. I want to clarify it completely before doing any such movement
1) Is it possible to replace existing socket and if yes how can I do this.
2) Server socket application listen at defined IP/Port and client socket application send request to that IP/Port only, but in case of WCF there is complete URI i.e. with IP/Port it also contains name of WCF Service, so how to do this.
3) Which type of binding configuration I need to use for it and if it is basic or wshttp can't it will effect performance of my application drastically.
When we use socket programming we do it at very low level and neither wcf, web service or remoting can perform good as compare to socket application. WCF provides so many feature but all this features are based on binding configuration and all this are at very high level as compare to socket application, so as far as performance is concern socket application will perform well as compare to wcf and if this are already build no need to replace it.
This is a rather difficult one to answer without knowing all the details of your application so I am going to attempt to answer this in a different order than you have asked it.
2) WCF supports multiple transport configuration. These are not limited to HTTP. For instance, the net.tcp transport doesn't use http at all but it does implement some complex functionality which you would need to replicate on the client side. For example Message Framing. This limits you choices to one of the standards-based approaches (unless you like doing that stuff).
3) Yes the http transports will probably be slower than direct socket communication. You will need need to profile exactly what features you require from WCF and what performance you need as there are many different configuration options which can have an impact on this.
1) So I guess this is the main answer. Yes it is possible but you will be required to make changes on both the client and server. While it is potentially possible for you to extend WCF to support your existing socket messaging format this could be a difficult and costly development process. Therefore you would want to implement this using Web Services (aka one of the http bindings) as opposed to net.tcp, msmq, etc.
Please note that WCF is actually extremely configurable with each layer having the ability to define custom transports, messaging, security, etc, etc. I would therefore suggest you read the documentation
We have a client/server system where all communications are done using a native protocol over a binary/SSL stream on TCP. All of our code is written in C# .NET 2.0 and some parts in 3.5. Our protocol is designed to support a variety of messaging patterns, namely Request/Response, and for lack of a better term, one-way messages from either the client or the server on an irregular basis.
Our objective is to add a feature to our system to carry our protocol over HTTP. There are several reasons for doing so, but I don't need to explain that here I think. Please tell me if I should.
The thought is to embed our protocol as application/binary in HTTP requests using the standard request methods ie., GET, PUT, POST, but not DELETE, and following the HTTP specification. This would be rather straight forward to do if our protocol was only request/response. The main concern comes from the one-way messages, and more specifically the unsolicited messages coming from the server. Another important concern is that HTTP is not oriented for persistent connections, but I believe with HTTP/1.1 this can be overcome. A third concern is that the server connections are not stateless.
We've been designing and prototyping this for a couple weeks, and we've come up with a couple ideas:
Refactor the code in the communication and protocol layers on both server and client sides. Although much of the code is shared, it is a lot of work that in all likely hood will not be a success. The question here is can this even be done with our poorly designed protocol?
Use a proxy approach. That is create an HTTP server using WCF and unwrap the HTTP messages and relay the native messages to and from our server over persistent connections. This would require a layer of abstraction on the client side that would actually maintain two connections to the proxy. One connection to perform request/response and the other to carry the unsolicited messages using a delayed response technique.
HTTP Tunneling which we haven't yet researched.
We're hoping that someone has encountered this challenge before and could lend some sound advice?
Please accept my apologies if this is the wrong place to post this question.
For the server initiated messages, you might consider WebSockets. According to Scott Guthrie's blog there is support for web sockets in ASP.Net MVC 4 beta.