I am currently new to C# and I need to understand simple server-client architecture!
I am currently trying to write a simple server/client program where basically a client can send a variable to a server and the server can send it to another client. Problem is that I am really blind to this as I am still very new to C# although I have some experience with Java (But still not with networking).
My question is:
How many files will i Have to write?
Can anybody be nice enough to provide me with a framework or example for a program like this?
What is a TCP server?
This is intended to be for an online game. One client will roll the dice and the server must show all the other clients that this is the value the first client rolled.
Any help would be greatly appreciated!
Answer to all of your questions: MSDN - Network Programming (.NET 4)
Since you are planning on TCP (because you want state) you need to develop a strategy. You'll get plenty of information about establishing a connection and moving some sort of data back and forth. Google will give you more than you can handle. Without doing all the work, here are a few steps to get you oriented.
1) Connection Registration - When a client comes online and wants to communicate with the server it first needs to say "Hey I'm here and want to role some dice." This initial handshake could be a connection id that is used for a heart beat and/or transactions. The server will use this to identify data and the respective thread if open.
2) Heart Beat - Now that the client has registered with the server the client is responsible for providing a heart beat saying it's still there and still planning to continue work. Typically every 3 - 10 seconds is good.
3) Develop the Request/Response protocol - For "every command" there will be a formal process. This formal process will include the connection id but also a request id. The client will not accept a response unless it receives the corresponding request id. Furthermore, every request will require a success or fail response to identify if it conforms to the API or what not. Within the request will be the command or action to perform. Some people use int's to dispatch a command id then use a switch on the id to call an entry-point method (cmd id = 1 is connect(), cmd id = 2 is rolldice(), etc). You might include additional payload that identifies the result from the command.
In short, 1 is the handshake, 2 is the keep-alive and 3 is passing data back and forth.
Now whether to use socket or WCF, I'd recommend to have a basic understanding of TcpClient programming then run with WCF. You'll be amazed how simple socket programming is but the overhead is a killer. Nothing to be intimidated by. It's a lot of work to coordinate calls, threads and not to mention security. WCF on the other hand does shave some of this overhead off.
I'd check out this question...
How to use socket based client with WCF (net.tcp) service?
1) The number of files will depend on your particular implementation. You can create this architecture as simply as 1 class for the server and 1 class for the client (you can have more than one class in a file). Depending on the complexity and choices you make during the design you could have many files or just a few.
2) A good tutorial for a simple TCP server / client can be found here
3) A TCP server is a process that waits for a connection from a TCP client. TCP stands for Transmission Control Protocol. From Wikipedia: TCP provides reliable, ordered delivery of a stream of bytes from a program on one computer to another program on another computer.
Related
I've seen many people talk about this any many people have criticised my attempt at doing this and said that I am not following the official rule of "What to send, who sends it, and how the other side responds." Is there even a rule for this? I'm not sure anymore...
Here is my current setup of communication.
Server: Gets alerted a new client has connected.
Server: Asks the client for the socket password.
Client: Sends a packet with the socket password.
Server: Okay, now give me some information on your device.
Client: Sends a packet including the device information
Server:
Okay, we've added you to the dictionary, thanks.
Now, if I tell the server to ask the client for the socket password straight away, what if the client hasn't called BeginReceive yet? What do I do about this?
I guess this question is answering my worries of the fact that I'm doing it wrong or I'm doing something wrong, how should I be doing this?
Who goes first? I've been told the client should only communicate with the server and the server should "respond" not "ask". Am I breaking any rules here?
Seegal. Ideally, you'd want to minimize the amount of calls the server is pinging down to the client. The server machine is your powerhouse, and if you're performing intensive work on a potato client PC, you may run into issues. Because you can't just tell people to upgrade their machines to use your service, that's on you.
The method I would use to hand up data would be a packet consisting of bitwise flags that will allow you to package multiple packet cases together without significant issue.
E.G.
[Flags]
enum NETWORK_CODES
{
CLIENT_CONNECT = 1 << 0,
CLIENT_DISCONNECT = 1 << 1,
CLIENT_PERFORM_ACTION = 1 << 2
}
This way, you can check for multiple flags at once and handle it accordingly.
if(packetFlags = CLIENT_CONNECT & CLIENT_PERFORM_ACTION) then
Authenticate(packetClient);
PerformAction();
end //Pseudo; don't hate. :D
It's a scalable solution, which is ideal for networking. If it doesn't scale, then you're in a bad spot and have to redo a whole bunch of code.
The server doesn't need to know if a client is there unless it's an active connection, which cuts back even further the amount of work you actually have to do.
There aren't any universal rules. Design your protocol according to your needs, and then you have rules. A socket is a peer to peer communication system (once the connection is established, in the case of TCP), which means that either peer may send any data at any time. It's purely up to the protocol engineer to design what can be sent, by whom, when, and how.
Think about Secure Sockets. SSL uses a protocol that allows the two peers to send and receive data through a secure channel however they wish, just like the underlying socket allows. On the other hand, think about HTTP. HTTP is purely a request/response oriented protocol. As such, it's far more restrictive than a protocol such as SSL, but it works perfectly well for the use cases it was designed for, along with many more, due to its inherent flexibility at the message level.
To answer the question "who goes first?", you can think of the act of connecting to the server as "going first". You can also think of the act of the server accepting the connection as "going second". So, that puts you back at square one; design your protocol however you see fit. Some protocols involve the server sending some sort of "welcome" message upon accepting the request, and some don't (HTTP, for example); either way is fine. In your case, it might make sense for the server to send a welcome message which contains some flags describing what is required to proceed, such as a password. The client would connect, consume the welcome message, and then proceed as appropriate.
To answer the question regarding whether or not the client has started reading from the socket, it isn't relevant. The server can send data immediately upon accepting the connection; the data will be buffered until the client application reads it by issuing read requests sufficient to consume it.
This is all more open-ended than is really appropriate for SO, but hopefully it helps.
The project is to build a messaging mechanism between a Python and C# program via ZeroMQ .
I want messages to be able to travel in/out from both ends at any time, which is NOT a basic request-reply model a.k.a. REQ/REP.
One way I can think of is to build a PUB/SUB model on two ports, i.e. two one way channels.
Is there any method to get a real duplex channel?
There are several ways to do this with ZeroMQ. I suggest using a DEALER/ROUTER socket pair:
Choose one program to be the "server", the other the "client".
The server will bind a ROUTER socket on a port.
The client will connect a DEALER socket to the server's ROUTER port.
(Note: this implies that the client must know the server's IP and port in advance.)
At this point the client can send messages to the server, but the server has no way to send to the client.
The client sends a "HELLO" message to the server.
The server will receive a message that includes the client's address and the HELLO message. Now the server can send messages to the client using the client's address.
DEALER/ROUTER is considered an "advanced" socket pair in ZeroMQ. My description here is very high level. You'll really need to read the docs to get the most out of ZeroMQ.
Oh yes, Sir!
Use the PAIR-PAIR or even the XREQ-XREP ought make it.
The best next step is to carefully read the respective Scalable Formal Communication Pattern archetypes' access-points' API documentation, so as to cross-check, that all pieces of pre-wired behavioural logic meet your Project needs and voilá, harness them in your messaging setup and tune-up the settings so as to meet you performance and latency needs.
That is this simple ( thanks to all the genuine knowhow hidden in these builtins ).
Using for years this very sort of inter-platforms integration among Python + C/MQL4 and other computing nodes, so well worth one's time to learn the powers and strengths of ZeroMQ.
I am writing a chat program between a server and a client in C# .Net. Both users, aside from chatting can engage in different activities like remote desktop and playing games together.
I have a few questions:
Multiple threads will be sending and receiving stuff from the client at the same time, that means every option need to identify which packet is meant for him and take data from it ? (Running a remote desktop while transferring a file a same time, the remote desktop thread will see the file packets arriving at stream but should ignore it, right?)
What's a good buffer size to set for the socket I will accept clients in?
Do I communicate in form of specialized class containing the data or try to keep the communication as a byte array I send over the stream?
The questions 2 and 3 are impossible for us to answer because we don't know what the communication and the requirements look like.
As for handling multiple threads: that is hard to get right, I'd use an existing solution.
I suggest you have a look at 0MQ as it might prevent you from reinventing the wheel.
There are .NET client libraries available: http://nzmq.codeplex.com/ and a nuget package http://www.nuget.org/packages/clrzmq/2.2.5 as well.
A good start is The Guide
For a quick example see this C# server and its hello world client in C#
I am in the need of creating a C# program that will run on couple of our local Windows client machines. These 'client' programs will have to take commands from a 'admin' program run on another machine.
The commands could be to reboot the client computers, return some local information about IP address etc back to the 'admin' program.
But how to accomplish this? I know a little about WCF but is that the right way to go?
If I go with WCF I will then have to make the client programs run a service method, like every second, to check for new commands. With sockets I establish a 'direct' connection and the client just waits for a command to receive - isn't that correct understood?
Which way would be the right way for me to go?
We are talking about ~10 clients and I want a maximum delay (send command - receive info back) of 1 second.
Any hints would also be appreciated.
Best regards
Duplex WCF server. Basically, the clients all connect into the server (so only 1 server), and the server uses its duplex channel to call back to the clients whenever it needs to. No polling, scales well, etc. The most headache you'll need to deal with is to set a long timeout in case that you don't send anything for a while so that the channels time out.
WCF will end up being much simpler in the end.
A couple of links:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
and
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
I hope those help.
You can make WCF clients act as servers and with command & control program connect to them that is no problem. Go for WCF if you don't want to mess with ugly stuff that sockets can bring. WCF can be configured nicely in app.config, and you can make it really self hosted command line application even so no need for IIS server. Configuration will be then resuable and easier to maintain.
You could use .NET Remoting which can provide a "push" backchannel from the server to the client (using "callbacks"). It does not need a 2nd TCP connection in the other direction so you don't need to mess with client's firewalls and routers.
Remoting is considered kind of obsolete but it has its places.
In any case I would not use a WCF polling technique. That leads to bad latency and a DDOS situation for the server.
If you can make the clients open a port then hosting a WCF service there is probably the best idea.
I would recommend a socket implementation as in the long run it probably gives you greater flexibility. You could create this from scratch yourself using the socket namespace. As an alternative you could use an off the shelf network library solution. Checkout lidgren and NetworkComms.Net.
Disclaimer: I'm a developer for NetworkComms.Net.
With the small number of machines and modest performance requirements you mentioned, I think WCF would end up being easier than sockets.
You might look into Duplex WCF. I've never used it, and WCF has given me headaches in the past any time I've needed anything unusual, but it's for the sort of problem you're talking about.
If all the machines are on one network, here's one creative alternative loosely inspired by message queues: you could use a database table as a place where messages appear and get read by clients at their leisure. The clients could just query it and say: get me all messages where MessageID > LastReceivedMessageID.
The downsides of that last approach is that (a) you're still doing polling although your database server should be able to handle it and (b) if you might ever need this outside of your network, you would need a VPN or a new solution.
you could use MSMQ... couldn't be easier to implement
http://msdn.microsoft.com/en-us/library/windows/desktop/ms711472(v=vs.85).aspx
I use MSMQ for a number of similar applications. Works perfectly.
Users in field with PDA's will generate messages and send to the server; users at the server end will generate messages which need to be sent to the PDA.
Messages are between the app and server code; not 100% user entered data. Ie, we'll capture some data in a form, add GPS location, time date and such and send that to the server.
Server may send us messages like updates to database records used in the PDA app, messages for the user etc.
For messages from the PDA to server, that's easy. PDA initiates call to server and passes data. Presently using web services at the server end and "add new web reference" and associated code on the PDA.
I'm coming unstuck trying to get messages from the the server to the PDA in a timely fashion. In some instances receiving the message quickly is important.
If the server had a message for a particular PDA, it would be great for the PDA to receive that within a few seconds of it being available. So polling once a minute is out; polling once a second will generate a lot of traffic and, maybe draim the PDA battery some ?
This post is the same question as mine and suggests http long polling:
Windows Mobile 6.0/6.5 - Push Notification
I've looked into WCF callbacks and they appear to be exactly what I want however, unavailable for compact framework.
This next post isn't for CF but raises issues of service availability:
To poll or not to poll (in a web services context)
In my context i'll have 500-700 devices wanting to communicate with a small number of web services (between 2-5).
That's a lot of long poll requests to keep open.
Is sockets the way to go ? Again that's a lot of connections.
I've also read about methods using exchange or gmail; i'm really hesitant to go down those paths.
Most of the posts i've found here and in google are a few years old; something may have come up since then ?
What's the best way to handle 500-700 PDA CF devices wanting near-instant communication from a server, whilst maintaing battery life ? Tall request i'm sure.
Socket communication seems like the easiest approach. You say you're using webservices for client-server comms, and that is essentially done behind the scenes by the server (webservice) opening a socket and listening for packets arriving, then responding to those packets.
You want to take the same approach in reverse, so each client opens a socket on its machine and waits for traffic to arrive. The client will basically need to poll its own socket (which doesnt incur any network traffic). Client will also need to communicate its ip address and socket to the server so that when the server needs to communicate back to the client it has a means of reaching it. The server will then use socket based comms (as opposed to webservices) to send messages out as required. Server can just open a socket, send message, then close socket again. No need to have lots of permanently open sockets.
There are potential catches though if the client is roaming around and hopping between networks. If this is the case then its likely that the ip address will be changing (and client will need to open a new socket and pass the new ip address/socket info to the server). It also increases the chances that the server will fail to communicate with the client.
Sounds like an interesting project. Good luck!
Ages ago, the CF team built an application called the "Lunch Launcher" which was based on WCF store-and-forward messaging. David Kline did a nice series on it (here the last one, which has a TOC for all earlier articles).
There's an on-demand Webcast on MSDN given by Jim Wilson that gives an outline of store-and-forward and the code from that webcast is available here.
This might do what you want, though it got some dependencies (e.g. Exchange) and some inherent limitations (e.g. no built-in delivery confirmation).
Ok, further looking and I may be closer to what I want; which I think i a form of http long poll anyway.
This article here - http://www.codeproject.com/KB/IP/socketsincsharp.aspx - shows how to have a listener on a socket. So I do this on the server side.
Client side then opens a socket to the server at this port; sends it's device ID.
Server code first checks to see if there is a response for that device. If there is, it responds.
If not, it either polls itself or subscribes to some event; then returns when it's got data.
I could put in place time out code on the server side if needed.
Blocking on the client end i'm not worried about because it's a background thread and no data is the same as blocking at the app level; as to CPU & batter life, not sure.
I know what i've written is fairly broad, but is this a strategy worth exploring ?