Advertisement

File update server

Started by August 17, 2003 07:59 PM
5 comments, last by Noods 21 years, 5 months ago
Im looking into creating a file update server, similar to the type of server a MMORPG has you hit before you log in. I think I can handle version checking, but how do you make a request to download a file? In other words, if I wanted the client to download the fileversion.dat, how would I request that on the client end, and how would I handle it on the servers end? Im using DirectPlay for my networking.
In our system we use apache as the system that serves the files.

In our system this is what happens:

The server has an internal version number that it uses. When we do a patch we up the version number. This tells all clients that they need to update their client. At the moment the updater is a seperate app.

So they run this app and it makes an HTTP request to the updater ( apache ) server and rips down an XML file that has a list of all the files and stuff to ID them ( like timestamps/md5s etc ). The client then generates another list of all the files it needs to update by comparing it with it's local xml list. It then does a series of HTTP requests to get the right files and stick them in the right location.

That way we only have to write a client application and let appache worry about serving out the files ( which it is really designed to do ). We use a lib called libcurl that does all the HTTP requests/ downloads for us.

Here's a link into our cvs for this app: cvs .

This may not be the best solution since it requires a full download and cannot do binary diffs. But it works ok for us.




-------
Andrew
PlaneShift - A MMORPG in development.



[edited by - acraig on August 17, 2003 9:37:31 PM]
Advertisement
I do a similar thing as Andrew is describing. Except we don't use apache

Bascially whenever we make a change to the program, afterward we run a supplimentary application that puts together what is essentially a text file that contains all the version numbers of all the files the client uses (we also use this as a hack prevention tool, so there are actually several checks that go into this file). <br><br>When the client runs, it requests this master file from the server. It uses the data from this file to look at it's current file set. If anything is missing or out of date, the client requests the updated file from the server. Similarly to what Andrew says, this downloads entire files rather than doing a binary update. You could do that, if you want to spend the time programming it, but I think it's probably overkill. My experience is that client files tend to be a whole bunch of small files rather than a few large &#111;nes, so it seems okay to just send them the whole file.<br><br>As to your specific question, I'm not entirely sure I understand what you're asking. You send a file the same way you send any piece of data. There's actually a number of ways to do it. The way I use is to let the client tell the server "I need file x segment y" and the server opens that file, reads that segment, and sends it back with an ID that says "this is file x segment y". When the client recieves the proper segment, it appends it to the previously recieved segments of that file (if it's the first segment, you create or overwrite the existing file). I break them into segments because I use UDP, and anything above about 500 bytes could in theory get fragmented and/or lost.<br><br>As for reliability and ordering issues, you could use TCP if you want and not have to worry about it <img src="smile.gif" width=15 height=15 align=middle> I use UDP exclusively in my program, so I make the client keep track of which file and segment it wants to get. If it gets the wrong file/segment, the packet is silently dropped. If the correct file/segment doesn't come through in a resonable amount of time (1 second I think is what we use), it is re-requested. Simple.<br><br>One last thing. The file that the client is running to get these updates can't itself be updated very easily (because you can't overwrite a currently running process). It can be done (obviously, because we did it), but it requires some manipulations. We detect this as a special case, and if the updater program requires an update, it is saved as with a temporary name, then the updater spawns a supplimentary program and shuts itself down. The supplimentary program then renames the temporary file back to the original name (overwriting the out-of-date updater program), spawns the new updater, and shuts itself down. It's a bit of a pain, but it is certainly possible.<br><br>HTH -Ron <br><br><SPAN CLASS=editedby>[edited by - RonHiler on August 18, 2003 10:10:42 AM]</SPAN>
Creation is an act of sheer will
I think I know exactly what I need now. That is to know how to transfer a file. I know how to create and send specified packets, but how do you breeak up, send, receive, and reassemble a program?
quote:
Original post by Noods
how do you breeak up, send, receive, and reassemble a program?


break up:
Check into the CreateFile, GetFileSize, SetFilePointer, and ReadFile Win32 functions

Send and Receive:
These are API specific, in your case DPlay. If you know how to send packets with DPlay, then same thing. Load the file segment you just read into the packet and send it just like you would any other bit of data. At the client end, receive it, just like you would any other data.

Reassemble:
Check into the CreateFile and SetFilePointer Win32 functions

-Ron
Creation is an act of sheer will
test...
Advertisement
> how do you break up, send, receive, and reassemble a program?

Ron''s method is correct. But here are a few notes about optimizations since it''s a DPlay/MS env.

a) Don''t load the file. Just memory-map it using the CreateFileMapping() & MapViewOfFileEx() function calls. It''s easier on the OS when the server is fully loaded.

b) You could send the buffer in one biggy ''SendTo()'' call; just make sure you use the DPNSEND_NOCOPY flag to prevent buffer duplication. And wait for the DPNMSG_SEND_COMPLETE message before unmapping the file from memory. Although DPlay 8.X handles large packet breakup, I just don''t like this method when files are large because it causes excessive memory consumption on the client side; it is very efficient when the files are relatively small. But that depends on the client''s memory footprint.

-cb

This topic is closed to new replies.

Advertisement