I've been looking around StackOverflow for a simple network TCP connection in C++ and all I seem to find are Java, Python and C#. I understand that Python or Java can set up easy connections but mostly I am programming a simple Yahtzee game in C++ and wanting to learn about the Networking in C++ because I have about a year's knowledge on C++ but don't have a strong grasp of these other languages, but alas I can't find a good simple set up to suit my needs.
I saw C++ Winsock P2P who has a set up but it has a few points that are tough for beginners.
In my game I am expecting the client to do most of the work (as I've heard that is a better implementation) but am not sure where to have the server take inputs and throw back outputs. I have the client rolling and displaying the rolls. Then I assume it would do all three rolls and once you've chose where to use your rolls, the client sends the server the placement in the score sheet and the dice rolls.
I understand the protocols of: you send something and the server can compute and send it back, but my question is, Do I have my client send a number (int choice = 12 for a yahtzee obviously) as a packet message and then send an array of dice rolls (int roll[5]) for the server to compute what goes in? or should the client do that work? This is what I don't know about the sending and overall set up.
This question is difficult to answer as it is really just your decision how to do it, and both approaches work. Some general aspects to consider in a server clients system:
Stuff that the client does is a lot more vulnurable to hacking. (e.g. If you generate the Random die result on the client, one could change the code and send your server wrong data, like always 12 or whatever)
Stuff that you do on the server impacts performance when your user number grows very large. Letting the client do it leaves your server processing power for other stuff
Oviously limit the amount of information you send when possible
So a general rule of thumb would be: let the server do anything that's 'dangerous', let the client do everything else. (Though unfortunately a lot of things are dangerous in this context)
In your case I would let the server do the dice rolling and send the results to the user.
Do I have my client send a number (int choice = 12 for a yahtzee obviously) as a packet message and then send an array of dice rolls (int roll[5]) for the server to compute what goes in? or should the client do that work?
You cant send an empty array and let the server fill that in. Remember, those can be seperate Computers. They cant access each others memory. You could just send a request to the server (Maybe an int constant) so it knows what to do(rolling a dice e.g.)
and then listen on the network for data and interpret e.g. the next 5 bytes that the server sends you as the dices it rolled.
Related
I'm really new to this whole socket and server development, I'm not yet familiar with how it all works.
I made a simple flash application that needs to communicate with a socket,
With that, I used a socket that supports AS3 and works on "Red Tamarin",
Well I'll get to the point:
I currently have a loop that always runs socket.receive()
It responds and even displays text that I send from my flash application.
My goal is to get a simple online flash game,
Probably use SQL / SQLite to save information and export it to players,
What I don't understand is how I can take it there..
What I thought I'll need to do is something like so:
On the server side:
Have a loop that runs as long as the server is alive, that loop should always check every connection it has with clients and wait for commands coming from them, such as log in, update player position, disconnect, request list of objects in given positions
Client side:
Send information to the server according to the action, like when a player moves, send the new position to the server in a similar way to this : "MovePlayer[name][x][y]"
Is my plan really how things should be?
And about the actual information being sent, I'm curious, will it be efficient to constantly send the server string data? (that's what I'm used to work with, not some weird bytes and stuff)
Thanks in advance!
You're on the right track. But I encourage you to first define a communication protocol. You can start by defining what a command looks like. For example:
COMMAND <space> PARAM1 <space> PARAM2 <line-break>
A few considerations on the protocol definition:
What if PARAM1 is a string and contains spaces? How can you tell the start and end of each parameter?
Your parameters could also contain a line-break.
If your client application is installed by your clients, they'll need to update it once in a while. To complicate even further, they may run an older version and expect it to work, even if you have changed your protocol. This imposes a need for protocol versioning. Keep that in mind if you require user interaction for updating the client part of your application.
These are the most fundamental considerations I can think for your scenario. There may be other important considerations, but most of them depend on how your game works. Feel free to amend my list if you think I forgot something OP should consider.
After defining what a command looks like, document all commands you believe your applications needs. Don't segregate definition of a command unless it becomes too complex or excessively long for some of your operations. Try to keep things simple.
Now back to your questions:
Is my plan really how things should be?
Yes. That's exactly how it should be.
And about the actual information being sent, I'm curious, will it be efficient to constantly send the server string data? (that's what I'm used to work with, not some weird bytes and stuff)
That depends on a number of factors:
Which protocol you're using (TCP, UDP, etc);
Number of concurrent clients;
Average time to process a command;
Do you broadcast updates to other players?
How you did implement your server application;
Physical contraints:
Hardware: CPU, memory, etc;
Network: bandwidth, latency, etc;
(source: it20.info)
look at this
https://code.google.com/p/spitfire-and-firedrop/
there you will see the basic of building a socket server with redtamarin
see in particular
https://code.google.com/p/spitfire-and-firedrop/source/browse/trunk/spitfire/src/spitfire/Server.as
the details is as follow, redtamarin basically use blocking sockets with select()
with a max hard coded FD_SETSIZE of 4096
see:
https://code.google.com/p/redtamarin/wiki/Socket#maxConcurrentConnection
so here what happen in your server loop
you basically have an array of sockets object
you loop every x milliseconds and for each socket
you ask if you can read it
if you can read on the socket, you then compare if this socket obj is the server
if it is the server that means you have a new connection
if not that means a client try to send you data and so you read this data
and then pass it to an "interpreter"
later in the same loop you check if the socket obj is still valid
and if you can write to it
if you can write and the socket object is not the server
then you can send data to the client
here the equivalent code in C for reference
http://martinbroadhurst.com/source/select-server.c.html
http://www.lowtek.com/sockets/select.html
for a very basic example look at socketpolicyd
https://code.google.com/p/spitfire-and-firedrop/wiki/socketpolicyd
https://code.google.com/p/spitfire-and-firedrop/source/browse/trunk/socketpolicyd/src/spitfire/SocketPolicyServer.as
and compare the implementation with Perl and PHP
http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
My situation: I would like to create a hobby project for improving my C++ involving real-time/latency programming.
I have decided I will write a small Java program which will send lots of random stock prices to a client, where the client will be written in C++ and accept all the prices.
I do not want the C++ client to have to poll/have a while loop which continuously checks for data even if there is none.
What options do I have for this? If it's easier to accomplish having a C++ server then that is not a problem.
I presume for starters I will have to use the boost ASIO package for networking?
I will be doing this on windows 7.
Why not just have the Java server accept connections and then wait for some duration of time. e.g. 10 seconds. Within that time if data becomes available, send it and close the connection.
Then the C++ client can have a thread which opens a connection whenever the previous one has completed.
That should give quite low latency without creating connections very often when there is no new data.
This is basically the Comet web programming model, which is used for many applications.
Think about how a web server receives data. When a URL is accessed the data is pushed to the server. The server need not poll the client (or indeed know anything about the client other than its a service pushing bytes towards it).
You could use a Java servlet to accept the data over HTTP and write the code in this fashion. Similarly, boost::asio has a server example that should get you started. Under the hood, you could enable persistent HTTP so that the connections aren't opened / closed frequently. This'll make the coding model much simpler.
I do not want the C++ client to have to poll/have a while loop which
continuously checks for data
Someone HAS to.
Need not be you. I've never used boost ASIO, but it might provide a callback registration. If yes, then just register a callback function of yours with boost, boost would do the waiting and give you a call back when it gets some data.
Other option is of course that you use some functions which are synchronous. Like (not a real function) Socket.read() which blocks the thread until there is data in the socket or it's closed. But in this case you're dedicating a thread of your own.
--edit--
Abt the communication itself. Just pick any IPC mechanism (sockets/pipes/files/...), someone already described one I think. Once you send the data, the data itself is "encoded" and "decoded" by you, so you can create your own protocol. E.g. "%%<STOCK_NAME>=<STOCK_PRICE>##" where "%%", = and ## (markers to mark start, mid and end) that you add on sender side and remove on receiver side to get stock name and price.
You can develop the protocol further based on your needs. Like you can also send buy/sell recommendation or, text alert msgs with major stock exchange news. As long as your client and server understand how the data is "encoded" you're good.
Finally, if you want to secure teh communication (and say you're not using some secure layer (SSL)) then you can encrypt the data. But that's a different chapter. :)
HTH
Question: Is it possible to update 100+ objects in the Flash Player over Socket Connections? More details and my own try's below!
Details
For my internship I got the time to create a multiplayer physics game. I worked for a steady three months on it. My internship is coming to an end and I couldn't finish my game.
My problem is that its hard to send multiple packets each time-step to the server and back. The packets I send are position updates of the objects and mouse of other clients.
I will try to explain the network/game flow.
Client connects to the server using the binary Socket class in AS3
Server ask for verification and client sends name and thumbnail.
Server waits until 4 clients are connected (Some matchmaking etc)
Server picks 4 clients and makes them run on a separate Thread(Combined as a Team)
Client sends his performance score to the server range 1-100.
Server makes the best client the host machine for the physics and the other 3 slaves
Host game sets up the level and makes around 1-100 shapes in the level(primary shapes and complex shapes like bridges, motors, springs)
Every time-step the host gets all updated property's of the shapes and sends them to the clients (x, y, rotation, sleep)
The client applys all the shape property's to the correct shapes
I tried different time-steps and noticed that until a time-step of 1/15 second the client(slave) won't notice any lagging in the game. I also tried to pick a lower time-step and tween the movement of the shapes but that did give some strange movement on the client(slave) side.
I will give an example of a single object update packet.
<O|t=s:u|x=201|y=202|f=automaticoo</O
<O|t=m:p|x=100|y=345|f=automaticoo</O
I noticed that the Flash Player can stack a lot of packets in the buffer before sending. For example if I send a lot of packets at once it stacks them up and send them together to the server. With faster time-steps you don't get more updates on the client(slave) side but more updates in the same packet row.
Tries
Use the new RTMFP(udp & p2p) protocol for updates. (little bit better in performance but less in reliability)
Code my entire socket server in c++ instead of Air(with the ServerSocket) (better in performance but noticed the lagging part is not the server but the Flash Player)
Use the ByteArray compress method and the AMF serialized format (performance about the same except the c++ server can't unserialize the messages)
Do you guys think it is possible in the Flash Player too handle so many update request each time-step.
Discoveries
There is a stick arena game that is multiplayer in ActionScript 3.0. They used a lot of tricking and even then I get a ping of about 300ms and it only updates the players constantly (4 players in a lobby).
Sorry for the long post.
I believe your problem comes down to type of game and data.
This again is broken up into:
server speed (calculations need in CPU + RAM requirements for world/player data)
connection speed (bandwidth on server)
data size (how much info is needed and how often)
player interaction form (event or FPS)
distance from client to server (ping)
MMORG
Eg. World Of Warcraft, is to my knowledge on the none-PVP worlds using a "client is a viewport" and "client sends keystrokes", "server validates and performs, and tells client what happens" on a CLIENT-SERVER base.
This gives the game a lot of acceptable latency as you only need to transfer commands from client and then results to the client. The rest is drawn on the client.
Its very event driven and from you click an icon or press a key, its okay that your "spell" needs some time to fire on the server. Secondly there is no player collision needed. This lets the server process less data too and keeps the requirements to the server CPU smaller.
Counter-Strike / Battlefield etc.
FPS, fast paced action, with quick response needs to get information about every detail all the time. This makes a higher demand on precision. Collision is a must for both player and weapons.
This sort of game usually doesnt handle more than 32 players on a single map, as they all need to be able to share their positions, bullets, explosions etc. very fast and all this data has to go through the server-validation which again is a bottleneck for any type of online game.
Network latency
In a perfect world this would be 0 ms, but as we all know. All the hardware from client to the server and back takes time. Both going through the network stacks and through the internet connection (switch, router, modem, fiber centrals etc) so the way many modern real time games fixes this is by "prediction". The let the server look at your direction and speed. Then they try to predict (much like the GPS do in a tunnel too) that you were last seen moving forward with a speed of +4 so given timeframe you have moved (timeframes x 4) - but what if you had slowed down or speeded up? then they either instantly "hyperjump" you from A to B in a split second and this you feel like a lagging game or they easy up to the real position so your "hero" slides a little faster or slower into the right possition.
This technique is explained many places on the net, so no need for details in here, but it takes time and tweaks to get a good performance from this - but it works and saves a lot of headaches for the programmers.
What network data is needed?
I read your question and thought: that could be compressed quite a lot. Secondly, I have made a Flash socket chat with pure ByteStream and that worked awesome. It was hard to get running for a start, but once I got it up and running it was fast.
The flash client/player itself isnt the biggest networking client, so expect a lot of lost speed there too. I would go for 10-15 fps for the networking part and then use a more RAW approach for the data sent back and forth.
Lastly, try to keep the data as simple as possible.
Eg. use COMMANDS/SHORTCUTS for certain data/events.
Like a server data bytestring could be: 0x99, 0x45,0x75,0x14,0x04,0x06
Where 0x99 means : BIG EXPLOSION at the following COORDS: (0x45,0x75)
Then 0x14 means: PLAYER 0x14 (player 20 in decimal) has moved to (0x04, 0x06)
So the staring opcode tells the networking protocol handler in your client and server what to expect next. (Its how a CPU knows how to read memory btw.)
For my chat I had commands for each type of data parsed. One for login, one for broadcasting, for for telling the name of a user etc. So once the client made a login, the client received a command + a packed of online users. This was only transfed once to the client. After that each attached client received a "new user online" command too with the name of the new user. Each client maintained its own list with current users and ID's so that I only needed to tell which client number say the text. This kept the traffic at a minimum. Same would go for coordinates or commands of what to do. "Player #20 goes north" etc. could be be 0x14, 0x41, 0xf0 (0x41 could be MOVE, 0xf0 could be NORTH, 0xf1 EAST etc.)
This physical distance to the game
This one you cant change, but you can put in some restrictions or make the servers run in multiple locations worldwide, depending on what type of game you wanna make. Amazon EC2 is a great platform for such projects as they have data-centers all over the world and then you can benchmark the users network against these and then redirect the users to the nearest datacenter where you are running a server.
Hacking/cheating
Also remember, if something gets popular and you start earning money on it, sooner or later SOMEONE will try to break the protocols or break down the accounts to gain access to servers, informations or cheat to get further items/points in the games. You could also be attacked by DDOS where they bomb your network with wrong data just to crash everything and render the game unusable.
Dont mind it so much for a start, just remember that once you go online, you NEVER know who in the world or where in the world they are. I'm not trying to make you paranoid, but there are sick people who will try to earn money by cheating others.
So think this into your structures, dont show data in network packages that isnt needed. Dont believe data from client always is correct. Validate data on server-side.
This also takes time if you have 100 active players at the same time.
But once you do it, you can sleep much better if it gets to be a big success for you, which I really hope.
That was my thoughts from experience. Hope some of it might be usefull eventhough I didnt quite answer if 100 players are possible.
Infact I would say: YES 100 players is possible, but it depends if they all move at the same time and there is collission testing involved and if you will accept lag or not.
Question: Is it possible to update 100+ objects in the Flash Player over Socket Connections?
Phosphor 2 seems to pull it off.
Maybe the best option was do the physics on server AND on each client, with synchronization (server object positions are overwriting client's). This way all clients get equal lags. Until discrepancy is low (as it should be) corrections will not be noticeable. If you use Box2D, you have both AS3 and C++ version ready. But this is totally different architecture, worth 3 month to implement by itself. What lag do you get on empty/simple arena? In limited time, simplification may be your only option.
I am making a multiplayer game in c++ :
The clients simply take commands from the users, calculate their player's new position and communicate it to the server. The server accepts such position updates from all clients and broadcasts the same about each to every. In such a scenario, what parameters should determine the time gap between consecutive updates ( i dont want too many updates, hence choking the n/w). I was thinking, the max ping among the clients should be one of the contributing parameters.
Secondly, how do i determine this ping/latency of the clients ? Other threads on this forum suggest using "raw sockets" or using the system's ping command and collecting the output from a file .. do they mean using something like system('ping "client ip add" > file') or forking and exec'ing a ping command..
This answer is going to depend on what kind of a multiplayer game you are talking about. It sounds like you are talking about an mmo-type game.
If this is the case then it will make sense to use an 'ephemeral channel', which basically means the client can generate multiple movement packets per second, but only the most recent movement packets are sent to the server. If you use a technique like this then you should base your update rate on the rate in which players move in the game. By doing this you can ensure that players don't slip through walls or run past a trigger too quickly.
Your second question I would use boost::asio to set up a service that your clients can 'ping' by sending a simple packet, then the service would send a message back to the client and you could determine the time it took to get the packet returned.
If you're going to end up doing raw-packet stuff, you might as well roll your own ICMP packet; the structure is trivial (http://en.wikipedia.org/wiki/Ping).
The enet library does a lot of the networking for you. It calculates latency as well.
I've already developed some online games (like chess, checkers, risk clone) using server side programming (PHP and C++) and Flash (for the GUI). Now, I'd like to develop some kind of game portal (like www.mytopia.com). In order to do so, I must decide what is a good way to structure my server logic.
At first I thought in programming separated game servers for each game. In this way, each game will be an isolated program that opens a specific port to the client. I thought also in creating different servers to each game room (each game room allow 100 clients connected on the same time). Of course I'd use database to link everything (like highscores, etc).
Then, I guess it is not the best way to structure a game portal server. I'm reading about thread programming and I think that is the best way to do it. So, I thought in doing something like a connection thread that will listen only to new connection clients (that way every type of game client will connect in only one port), validate this client (login) and then tranfer this client to the specific game thread (like chess thread, checkers thread, etc). I'll be using select (or variants) to handle the asynchronous clients (I guess the "one thread per client" is not suited this time). This structure seems to be the best but how do I make the communication between threads? I've read about race conditions and global scope variables, so one solution is to have a global clients array (vector or map) that need to be locked by connection thread or game thread everytime it is changed (new connection, logout, change states, etc). Is it right?
Has anyone worked in anything like this? Any recommendations?
Thanks very much
A portal needs to be robust, scalable and extensible so that you can cope with larger audiences, more games/servers being added, etc. A good place to start is to look into the way MMOs and distributed systems are designed. This might help too: http://onlinegametechniques.blogspot.com/
Personally, I'd centralise the users by having an authentication server, then a separate game server for each game that validates users against the authentication server.
If you use threads you might have an easier time sharing data but you'll have to be more careful about security for exactly the same reason. That of course doesn't address MT issues in general.
TBH I've been doing a voip system where the server can send out many streams and the client can listen to many streams. The best architecture I've come up with so far is just to bind to a single port and use sendto and recvfrom to handle communications. If i receive a valid connect packet from a client on a new address then I add the client to an internal list and begin sending audio data to them. The packet receive and response management (RRM) all happens in one thread. The audio, as it becomes ready, then gets sent to all the clients from the audio thread. The clients respond saying they received the audio and that gets handle on the RRM thread. If the client fails to respond for longer than 30 seconds then I send a disconnect and remove the client from my internal list. I don't need to be particularly fault tolerant.
As for how to do this in a games situation my main thought was to send a set of impulse vectors (the current one and 'n' previous ones). This way if the client moves out of sync it can check how out of sync it is by checking the last few impulses it should have received for a given object. If it doesn't correspond to what its got then it can either correct or if it is too far out of sync it can ask for a game state reset. The idea being to try and avoid doig a full game state reset as it is going to be quite an expensive thing to do.
Obviously each packet would be hashed so the client can check the validity of incoming packets but it also allows for the client to ignore an invalid packet and still get the info it needs in the next update and thus helping prevent the state reset.
On top of that its worth doing things like keeping an eye on where the client is. There is no point in sending updates to a client when the client is looking in the other direction or there is something in the way (ie the client can't see the object its being told about). This also limits the effectiveness of a wallhack packet sniffing the incoming packets. Obviously you have to start sending things a tad before the object becomes visible, however, or you will get things popping into existence at inconvenient moments.
Anyway ... thats just some random thoughts. I have to add that I've never actually written a multiplayer engine for a game so I hope my musings help ya a bit :)