Sign in to follow this  
BaronBigman

Updating clients with new graphics (DXPlay)

Recommended Posts

My project: Delphi 2005 + Delphi X I am using DXPlay (and this Tutorial: http://www.cerebral-bicycle.co.uk/viewdoc.asp?doc=36) for networking in my project, but now I want to add the ability to update clients with new graphics. I am new to network programming, and i cant get this to work. Ideally I would want to send a TDXImageList to the clients, but I would settle for sending one BMP file at a time, but alas, i cant do that either! Any help or suggestions would be appreciated! Thanks

Share this post


Link to post
Share on other sites
You can send a file (which includes bitmaps or your own favourite texture format) via something like the following pseudo:
byte[] ba = new byte[65536];
int r;
File f = new File("whatever.bmp");
Socket s = something;
while(r = f.read(ba, 65536)){
s.send(ba, r);
}

And the opposite (read from the socket, write to the file) in the client.

Share this post


Link to post
Share on other sites
Cheers,

I kinda see what your doing, but to be honest, I cant really get it to work, my client dosent know when the end of the file has arrived. Im using ICS from www.OverByte.be if anyone knows how to implement the socket properly, or knows of a begginners guide for this kind of thing, then it would really make my day....

Share this post


Link to post
Share on other sites
Oh, of course. Sorry, I forgot a vital step. If you're using a message-based protocol (which you should be), your TCP stream will be split up into 'messages' of known length. This would normally be abstracted away into a message-passing library but effectively just involves sending the length of the message before the content.

So in this case, the size would be the length of the file, and the end of the message would mean the end of the file.

Share this post


Link to post
Share on other sites
Even if you're not message-based, you can easily format each file as part of a stream.


void send_file(char const * name, void const * data, size_t size, int socket)
{
if (strlen(name) > 127) throw std::runtime_error("too long name");
if (size > 0xffffff) throw std::runtime_error("too large file");
std::vector<char> message;
// packet type
message.push_back( kMessageNewFile );
// marshal name string
message.push_back( (char)strlen(name) );
message.insert( message.end(), name, name+strlen(name) );
// marshal data size
message.push_back( (size >> 16) & 0xff );
message.push_back( (size >> 8) & 0xff );
message.push_back( size & 0xff );
// send header
if (::send(socket, &message[0], message.size(), 0) != message.size())
throw std::runtime_error("send() header failed");
// send actual data
while( size > 0 ) {
size_t toSend = size;
if (toSend > 4096) {
toSend = 4096;
}
long sent = ::send(socket, data, toSend, 0);
if (sent < 1) {
throw std::runtime_error("send() data failed");
}
size -= sent;
data = ((char const *)data) + sent;
}
}


On the receiving end, you'd be decoding the packet type byte (kMessageNewFile), the length of the name, the name, the length of the data, and the data.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this