Internet communication between programs, without worry in C#? - c#

I want to provide a direct connection between two instances of my program, which are located on two different computers.
I already have the means to obtain the IP addresses, but how do I make a connection between my programs and have no trouble with the firewall or ports?
I need to send serialized objects through the connection.
Edit2: The specific term is peer-to-peer connection.
Edit: I see I need to explain the "no trouble" part.
First, when a program attempts to communicate to the internet, the annoying Windows Firewall permission dialog opens.
On Windows 7, you have two checkboxes:
1. Allow on private (home/work) networks, which is checked by default and, sometimes, cannot be unchecked.
2. Allow on public networks, which is either checked or unchecked by default...
NO ONE I know makes sure that all the check boxes are checked. NO ONE.
This can interrupt the program sometimes in bad ways, without people knowing!
Next... Most people are behind a router and routers usually block all the requests to undefined ports, unless the rules are changed.
Nobody will accept to add these rules just to use a program. Nobody.

You can use WCF for this purpose.
It doesn't solve 'all' network problems though, but I doubt any technology would.

It kind of sounds like you're looking for a way to bypass firewalls so that your users won't have to deal with that kind of stuff while using your program.
If that's indeed the case, think about it this way. Would the Windows Firewall be good at its job if it allowed you (or anyone else) to do that?
What you might want to do is open up a port using TCP and send serialized objects over it to a target listener, which knows how to decode those bits back to objects.
If you need that port open, your users will have to allow that. If they're running a firewall that blocks it, then that firewall needs to be properly configured to allow your program to interact with the target computer.
You can use TcpClient, TcpListener (System.Net) and BinaryFormatter (System.Runtime.Serialization) to send serialized objects over TCP.
Remember you need to specify your custom classes as [Serializable].

So, using a TcpClient and a TcpListener works... as long as I forward the ports on the listener's router.
So this is not an option.
I ended up using my database to queue commands and check for them every once in a while, and dequeue them when necessary.
For the moment, I cannot find any good answer.

Related

C#\Java and Java\C# pairs of client\server - graceful disconnect when client(socket) is closed

This is maybe more of a thing for discussion than a question.
Background:
I have two pairs of server/client, one pair written in Java and one written in C#. Both pairs are doing the same thing. No problems when I am using Java\Java and C#\C# combination. I would like to make combinations of Java\C# and C#\Java work as well. No problem with I\O, I am using byte array representing XML formatted string. I am bound to use TCP.
I need to care about graceful disconnect, in Java there is no such thing. When you close socket of client, server side socket remains in passive close state - therefore the server thread handling this socket is still alive, and in case of many clients I could end up with thousands of unnecessary threads. In C# it is enough to call TcpClient.Available to determine, whether there are data in buffer or whether the client has been closed(SocketException). In Java I could think of two approaches:
you have to write something to the underlying stream of socket to really test, whether the other side is still opened or not.
you have to make the other side aware, that you are closing one side of connection before you close it. I have implemented this one, before closing client socket I am sending packet containing 0x04 byte(end of transmission) to server, and server reacts on this byte by closing the server side of socket.
Unfortunatelly, both approaches have caused me a dilemma when it comes to C#\Java and Java\C# pairs of client\server. If I want these pairs to be able to communicate with each other, I will have to add code for sending the 0x04 byte to the C# client, and of course code handling it to C# server, which is kind of overhead. But I could live with unnecessary network traffic, main problem is, that this C# code is part of core communication library which I do not want to touch unless it is absolutely necessary
Question:
Is there other approach in Java to gracefully disconnect, which does not require writing to underlying stream of socket and checking the result so I do not have to handle this in C# code as well? I have a free hand when it comes to used libraries, I do not have to use only Java SE\EE.
I have given (what I think is a) concise explanation on this "graceful disconnection" topic in this answer, I hope you find it useful.
Remember that both sides have to use the same graceful disconnection pattern. I have found myself trying to gracefully disconnect a Client socket but the Server kept sending data (did not shutdown its own side), which resulted in an infinite loop...
the answer was apparent. There is nothing like graceful disconnect in C# as well, it is about TCP protocol contract. so there is same problem as in Java, with one slight difference, you can workaround on certain circumstances -> if you send 0 bytes through NetworkStream and then check TcpClient.Connected state, it is somehow correct. However from what I have found on the internet this is neither reliable nor preffered way how to test connection in C#. Of course in my C# library it has been used. In Java you cannot use this at all.
So my solution with sending "end of transmission" packet to server when client disconnects is solid, I have introduced it in C# library as well. Now I just tremble in fear for the first bug to emerge...
last point, I have to implement also some kind of mechanism that would collect handling threads on server for crashed clients. Keep that in mind if you are doing similar thing, no client is bound to end expectedly;)

How would I make a program to monitor another system's vitals with a remote connection?

I'm looking to write a custom program in VB.NET / C++ / C# that would allow me to monitor a system's vitals over a Remote Desktop Connection.
I'm only looking for tips on how to implement a connection like this in code (eg. is it just a simple object or call to a WScript function? or is it much more sophisticated?). As to the specifics of operation after making the connection, I have that figured out based on another program which shares some similar features.
I would definitely look on Google and self-teach this, but I don't even know where to begin / what to search for. Some advice into this would be amazing, thanks!
EDIT: This doesn't have to go through an RDP connection, I'm definitely looking for better ways. Reason I mention RDP is because I currently do this manually over an RDP connection, but I don't wanna have to constantly open the window.
I don't think the RDP protocol is the right solution for this. Other mechanisms were invented for this, such as WMI.
WMI is a scriptable interface that allows you to query the local or remote computer's information. You can use your tool of choice - C#, VBScript, or my personal preference - Powershell. Here is an example of how to get all of the processes on a remote machine.
EDIT:
This doesn't have to go through an RDP connection, I'm definitely looking for better ways. Reason I mention RDP is because I currently do this manually over an RDP connection, but I don't wanna have to constantly open the window.
Then ignore everything below the line. Really.
The RDP protocol is very specialized for sharing specific resources. Namely the screen, disks, clipboard, printer, ports, and sound. That's it for what's out-of-the-box. The best thing you could possibly do is occasionally monitor the contents of a file with the RDP protocol - and it is cumbersome and slow.
I'd encourage you to look at alternative solutions like WMI instead.
That said, it is possible to do this with RDP's support for Virtual Channels. You could create a scriptable virtual channel to accomplish this (which is no easy feat). You would have to write a client and server. Your server side functionality would report the information you are interested in monitoring, and the client side would receive it. Again, I would stress that this is not the correct solution.

View current opened netNamedPipe channels?

Is there any way I can determine which netNamedpipe channels are currently open? This will help me debug my WCF Client/Server and make sure I am closing my channels properly.
This is similar to the netstat tool for network connections, but for netNamedPipes instead.
There is no tool to do this, as far as I am aware.
You can use Process Explorer to find what handles to named pipe objects a process is holding, but this will not really answer your question. To recognise pipes which are created for WCF NetNamedPipeBinding channels you need to know what you are looking for. WCF pipes will incorporate a GUID in their name, looking something like this:
\\.\pipe\197ad019-6e5f-48cb-8f88-02ae11dfd8c0
See here for more on this.
However, the fact that a handle exists doesn't per se tell you anything about the state of the channel. There is a WCF pooling mechanism for pipe connections, so even if the channel is properly closed this does not guarantee that the pipe connection itself has been dropped and the handle released (though if you were to see a process gradually acquiring more and more handles that would suggest there might be a problem with channel cleanup).
If you want to confirm that channels are being cleaned-up promptly I would suggest you enable WCF Tracing in verbose mode: this will tell you exactly what is going on.
You can use Process Explorer to see what pipes a process has open:
http://technet.microsoft.com/en-us/sysinternals/bb896653
SysInternals has a command called PipeList. I believe you can download the command separately here:
http://technet.microsoft.com/en-us/sysinternals/dd581625

C# - 2 clientside programs trading variable information -- is there a better way?

I am attempting to send player information from my Game to my network client to then be sent off to the server.
Currently the ClientNetwork -> ClientGame relationship is held with XML files. They read/write back and forth at very high speeds. If you use just one XML file for this trade, one will "hog" the file at times, making a kind of lag when one cannot read because the other is viciously writing and rewriting.
To fix this I have 2 of each of my XML files. If it cannot read one, it will read the other. In theory they should be using both of them, since it'd be a tradeoff from one to another. Not working up to par.
But my main problem is just the usage in general of XML is very sloppy, dozens of try-catch statements to make sure they're all happy (and my personal favorite, try catches within try catches -- WE HAVE TO GO DEEPER)
I am just curious of if there is a better way to be doing this. I need a static point of variables that can be accessed by both client side programs. I'm afraid someone is going to say databases...
I'd like to state for anyone who is looking into this as well and stumbled across this page that Shared Memory is awesome. Though I have to convert all strings to characters and then to bytes and read them one by one, in the whole it's ALOT better than dealing with things that cannot read/write the same file at the same time. If you wish to further understand it rather than just use it, go to this link, it explains a lot of the messaging varieties and how to use them.
Yes there is!
The term you are looking for is interprocess communication - communication between two processes on the same machine.
There are various methods which allow two processes on the same machine to communicate with each other, including:
Named pipes
Shared memory
Sockets
HTTP
Fortunately C# applications can simply use the WCF framework to perform IPC (interprocess communication) using one of the above, and let the WCF framework take care of the difficult bits! Here are a couple of guides to get you started (there are many more):
WCF Tutorial - Basic Interprocess Communication
Many to One Local IPC using WCF and NetNamedPipeBinding
Also, one of the neat things about WCF is that you can also use it to communicate between different machines simply by changing the "Transport" (i.e. the communication method) to one which works over a network, (e.g. HTTP).
If you are targetting .Net 2.0 then you should look into either .Net remoting or web services instead.
A simple TCP stream jumps out at me. Have the network client open a listening TCP socket, and have the game connect to the network client. You could continue to send the same XML data you're already writing, if you like.
I agree with the tcp/ip socket answer proposed by David. I would simply submit the data to a socket on the local pc and have the other application listen to the socket. You can transmit data easily and quickly using this method and it will work no matter what version of the .net framework you are targeting.

How to create an easy-to-program-for server for many clients in C#?

I suppose similar questions were already asked, but I was unable to find any. Please feel free to point me to an existing solutions.
I'll explain my scenario. I'd like to create a server application. There are many clients (currently only a few dozens, but it should scale up to 1000+) that connect to the server (which is running on a single machine).
Each client periodically sends a small amount of data to the server to process (processing is quick). The server can also send small amounts of data to each client on a regular basis. The response time should be low (<100 ms), but realtime or anything like that is not required.
My first idea was back from when I was still programming in VB6: Create a server socket to listen to incoming requests, then create a client socket for each possible client (singlethreaded). I doubt this scales well. It is also difficult to implement the communication.
So I figured I'd create a listener thread to accept new client connections and a different thread to actually read the incoming data by the clients. Since there are going to be many clients, I don't want to create a thread for each client. Instead, I'd prefer to use a single thread to read all incoming data in a loop, then either processing these data directly or creating work items for a different thread to process. I guess this approach would scale well enough. Any comments on this idea are most welcome.
The remaining problem I'm worried about is easy of communication. The above solution seems to require a manual protocol, possibly sending ASCII commands via TCP. While this would work, I think there should be a better way nowadays.
Some interface/proxyish way seems reasonable. I worked a bit with Java RMI before. From my point of understanding, .NET Remoting serves a similar purpose. Is Remoting a feasible solution to the scenario I described (many clients)? Is there an even better way I don't know of yet?
Edit:
This is not in LAN, but internet, if that matters.
If possible, it should also run under Linux.
As AresnMkrt pointed out, you should try WCF.
Just take it as is (with netTcpBinding, but don't forget to switch security off) and create a Tracer Bullet - measure if performance meets your requirements.
If not, you can try to tune WCF - WCF is very extensible, and you can modify message serialization to send ASCII messages as you want.
Are you sure you need a binary protocol? Rather, are you sure you need to invent a whole new protocol where plain RESTful service with JSON/XML will suffice? WCF can help you in this regard a lot.

Categories

Resources