使用者工具

網站工具


network:network_programming

Book & Reference

Multiplayer and Network Programming

http://www.gamedev.net/community/forums/showfaq.asp?forum_id=15

Q0) I have this dream to start the most uber MMORPG evar but I don't know whether I can write the networking part in javascript. Would Visual Basic be better?

Q1) I want to start learning about networking. Where do I go?

Q2) Should I use DirectPlay or WinSock?

Q3) Should I use TCP or UDP?

Q4) If TCP makes sure the data gets to me without me needing to worry about it, why would I want to use UDP, which makes no such guarantees?

Q5) Is UDP faster than TCP?

Q6) I'm sending data with TCP, but my ping times are insanely high! It seems the data is slowed down somwhere on the way. What's wrong?

Q7) Is there an easy wrapper on top of UDP which will give me reliable packets for packets that need it?

Q8) What are some other networking libraries that often get mentioned in the forum?

Q9) Why can't I host a game when I'm behind a firewall or DSL router?

Q10) Should I spawn a thread per connection in my game code?

Q11) Should I use blocking sockets, non-blocking sockets, or asynchronous sockets?

Q12) What should I put in my network packets, and how often should I send them?

Q13) Why can't my FD_SET be bigger than 64 on Windows, and 1024 on UNIX?

Q14) I'm trying to send two packets over TCP, but it seems like they arrive “merged” or one packet disappears on the receiving end. What's going on?

Q15) How do I send a struct using send() or sendto()?

Q16) How do I interpolate my character based on server lag, and still keep it in sync with the server?

Q17) Is a peer-to-peer MMORPG a good idea? Wouldn't that save a lot on server bandwidth?

Q18) How do I get the IP address of the machine I'm running on?

Q19) No, really. I want to use TCP for my MMORPG.

Q20) I need a server that will stay up longer than my cable modem, but typical web hosts won't let me run my own server program. What are my options?

Q21) How does my client find the server it wants to talk to?

Q22) Why do I get an error when trying to open a new socket soon after I've closed a socket on the same port?

Q23) Do I need to send 4 bytes to send a float for position or heading in my entity state update packets?

Q24) How do I find a server for my game? Currently, I'm hard-coding an IP address, but that won't work when I ship it to others.

Q25) How do I synchronize the clocks between the client and the server?

Q26) How can I see what's going on on my network? Is there a good networking debugging tool?

Q27) I'm using client prediction by simulating objects client-side, but update the entity positions to the “true” positions when I receive updates from the server. This causes snapping in the position on-screen. How can I hide this snapping?

Q28) What does the canonical chat server code look like?


Q0) I have this dream to start the most uber MMORPG evar but I don't know whether I can write the networking part in javascript. Would Visual Basic be better? A0) The best place to start is here. After you have assimilated the full knowledge of that highly relevant article, you're ready to move on to answer 1 below, or a link such as this.

Q1) I want to start learning about networking. Where do I go? A1) Try Beej's Networking Tutorials. You could also try the intro section right here on this site. Also try the WinSock FAQ for sockets programming, especially as relates to Windows, and the GameDev.net WinSock tutorial. Last, the MSDN section on WinSock has a decent overview section, and good reference documentation.

Q2) Should I use DirectPlay or WinSock? A2) As of Summer Update 2004, Microsoft has put DirectPlay into “sunset” mode, where they will not develop the API further. Microsoft now recommends you use WinSock for networking, until the re-cast X-box Live! technology is rolled out for PCs, probably around Longhorn time-frame. If you're on Linux, MacOS, or some other platform like that, life is easier: you only have regular sockets to work with. Luckily, sockets and WinSock code can look very similar if you stick to the Berkeley sockets functions of WinSock, and avoid WSA functions; you can write quite portable programs with a little bit of thought.

Remember to include <winsock2.h> before including <windows.h> in your win32 program, or compile errors will ensue. Also, always start your WinSock program with WSAStartup( MAKEWORD(2,2), … ) to get version 2.2 of WinSock, as the older versions have bugs and limitations that you don't want to deal with. Finally, you need to link with ws2_32.lib on Win32 when using WinSock.

Q3) Should I use TCP or UDP? A3) There are at least four different kinds of games as far as networking is concerned: Turn-based games, Real Time Strategy games, Role Playing Games, and Action Games. Briefly, if you're turn-based, you should go with TCP because it's simpler, unless you need peer-to-peer NAT punch-through. For RTS games, you're usually best off using TCP, although UDP can make sense in extreme cases. For role playing games, the story is less clear – action-based RPGs with lots of kinetics, like City of Heroes, use UDP, whereas slower RPGs and MUDs often stay with TCP. For action-based games like first-person shooters or racers, you should absolutely use UDP.

Q4) If TCP makes sure the data gets to me without me needing to worry about it, why would I want to use UDP, which makes no such guarantees? A4) TCP is a stream-based protocol. What goes in one end, will come out the other end, in order, with no duplication or packet drops. This is very convenient when correctness is paramount. However, to make this guarantee, TCP must suspend all packet delivery to the receiving end, if one packet is lost, until that packet can be detected as lost and re-sent. This may cause hick-ups of several seconds for a single packet that's lost!

Q5) Is UDP faster than TCP? A5) UDP uses slightly smaller headers per packet than TCP, which may give you marginally better throughput on narrow channels (such as modems). UDP will also deliver any received packet as it is received, without waiting to re-order packets, so if latency is more important than correctness of the underlying channel, then UDP will introduce less jitter in your game, and gameplay will be smoother.

Q6) I'm sending data with TCP, but my ping times are insanely high! It seems the data is slowed down somwhere on the way. What's wrong? A6) When you send data on a TCP connection, the network packet typically implements something called Nagle's algorithm. This will make the system not immediately send data if you don't fill up an MTU's worth of data in a single write; instead it will sit and wait for some time (200 milliseconds is typical), hoping that you will write more data that it can coalesce into a single packet. You turn OFF this delay by turning ON the TCP_NODELAY socket option.

Q7) Is there an easy wrapper on top of UDP which will give me reliable packets for packets that need it? A7) I hear Enet is pretty good, although the documentation is pretty sparse.

Q8) What are some other networking libraries that often get mentioned in the forum? A8) Low-level “sockets portability” libraries include: Enet HawkNL PLib/Medusa SDL_net lidgren network library (for C#) Boost ASIO (asynchronous I/O)

High-level “we give you structure” libraries include: ClanLib Net-Z/Eterna Nevrax/NEL OpenPlay OpenSkies OpenTNL RakNet ReplicaNet ZoidCom Etwork

If you want to make an MMORPG, there are some libraries as well:

PlaneShift is open source to the core (including art). Nevrax/NeL is open source, but tools/art is commercial (The Saga of Ryzom). RealmCrafter comes with tools, starter art, and a small game; it's $55. Torque plus RPG Kit at $249 total make for an RPG toolkit.

There are also several commercial libraries that provide more than just networking, such as Forterra Systems OLIVE, the Multiverse platform, Sun Project Darkstar, etc, but those are too extensive in scope to easily fit in the “multiplayer” forum.

Note that, with all of those libraries, scaling to a large number of players is as much derived from how you design your game, as from any specific technology (or lack thereof).

Mention (or the absense of mention) of a specific library does not mean gamedev.net or the moderator endorses (or counter-endorses) that library. The most commonly mentioned libraries are Enet, RakNet and OpenTNL, although your mileage may vary.

Q9) Why can't I host a game when I'm behind a firewall or DSL router? A9) You're probably suffering from the Network Address Translation in the firewall/router. There's a number of documents describing how to set up an introducer system to punch through NAT and allow you to host from behind a firewall. Try this web page or wait for my upcoming article in Game Programming Gems 5 (out spring 2005).

Q10) Should I spawn a thread per connection in my game code? A10) The short answer is “likely no.” The longer answer is that, if you're using UDP, you should only need a single socket, from which you can read a packet, process a packet, repeat. If you're using TCP, you will need a socket per player, but the players are likely sharing and affecting a single world state inside the program, which needs to be protected by locking; thus, the extra threads would just end up blocking on locks anyway, so using select() and reading out what's there, then processing it, is recommended. Some users find “co-operative threads” or fibers to be a nice middle ground, because it gives some of the advantages of real threads (a stack per context) without the locking overhead (because yield is explicit).

Q11) Should I use blocking sockets, non-blocking sockets, or asynchronous sockets? A11) On UNIX (at least Linux), asynchronous sockets are not generally available, although you can arrange to get a signal when “any fd” is ready (FIOASYNC). If you're on windows, and you're prepared to deal with the significant management overhead, they can lead to good performance. However, using non-blocking sockets in concordance with select() is usually not only the easiest to implement correctly, but will also perform well – I recommend not doing anything fancier unless a profiler tells you to (i e, until oprofile tells you you're spending 10% of your CPU time inside select()).

Blocking sockets makes it much harder to write a real-time game, because, well, they block! If you're writing a file transfer program or something like that, especially if it's point-to-point (only a single connection), blocking TCP sockets are very easy to work with, assuming you can live within the constraints of that model.

If you are Windows-only, a high-performance alternative is Overlapped I/O on sockets.

Last, there's a good write-up of TCP/socket performance, with some comparisions of Unix and Windows (although mostly Unix-based), that's recommended for people worried about throughput.

Q12) What should I put in my network packets, and how often should I send them? A12) That depends on your goals and your game. For an FPS style game, you might want to read about how Quake III, Unreal and Tribes does it. (If that link doesn't work, try webarchive.org, although that's very slow. For a turn-based game, the most important thing is to make sure that players stay in sync; bandwidth and latency doesn't play into it as much. For a real-time strategy game, bandwidth compression becomes paramount, because there is often a large number of units moving around. A good article (known as “1,000 Archers”) is on GamaSutra.com. For data compression approaches, Jon Blow wrote a series in Game Developer: here. There's also this thread on the forum about RPG and RTS command/packet encoding that might be helpful. For MMORPGs, the typical solution is to send the position & state of some entity (possibly with delta compression and periodic baselines), every so often, where you send it more often the closer the player is to the entity. If you have a good link describing this, please let me know!

Q13) Why can't my FD_SET be bigger than 64 on Windows, and 1024 on UNIX? The implementation of FD_SET on Windows is a big array of socket values, and adding, testing, and removing sockets is linear in number of sockets in the set. Luckily, modern caches make this not be as terrible as you might first think, but hard-coding a solution that loops over the FD_SET specifically to extract ready sockets is probably a good idea. Windows does this because its sockets are not low integer file descriptors. The implementation on UNIX is a bit mask, where you set bit N if you want to examine file descriptor N. Both of these implementations can easily be extended if you declare your own file set structure compatible with the operating system structure, but bigger. Most system headers will also allow you to define FD_SETSIZE on the command line, to make for a bigger set size without re-declaring the structure.

Q14) I'm trying to send two packets over TCP, but it seems like they arrive “merged” or one packet disappears on the receiving end. What's going on? TCP is a stream protocol. Everything you push in one end will arrive, in order, out the other end. However, the “boundaries” you establish by calling send() on one end are not preserved in the stream. The TCP implementation may split the data such that multiple send() calls get merged into one recv() call, or so that a single, large send() gets received through multiple recv() calls. To construct message semantics on TCP, each time you send a message, you have to precede it with the length of the message, as a short or a long (use htons() or htonl() to make it cross-platform). Then write that many bytes of message. On the receiving side, you'd first read out the length (a short or long) and then that many bytes of message data, re-constituting each message sent from the other end.

and so on……XD

network/network_programming.txt · 上一次變更: 2013/06/10 16:16 由 wenpei