Skip to main content
gamedev.net
🔒 Locked

Send buffer?

Started by qpwoeiruty Dec 31, 2006 at 1:58 AM 2 replies 1.3k views
Original Post
qpwoeiruty
qpwoeiruty
[font=arial, verdana, tahoma, sans-serif][size=2]blah[/font]
prh99
prh99
Quote:
Original post by Kada2k6
This is something I have been thinking about for a while.....

Let's say I've written a server that distributes the current game map when a client connects. This map could be pretty big, maybe it's several megabytes (just as an example). In this case I've written a sort of graphical MUD server/client.

I have sort of figured out that taking this file and just send() it to the client in one call is not very good, and somehow not realistic. If the file was 70 mb, for example, would one send() even do anything? Would it crash?

I'm thinking there needs to be some kind of send buffer. When I want something to be sent to a client, I should put it in a buffer first, and then send() small portions of that buffer over a period of time until the buffer is empty again.

But that leads to some questions from my side:

1) Is this right?

2) How much (data in bytes) should be sent with each send() call?

3) How long should I wait until I do the next send?

4) Surely these values would differ depending on the client's connection speed?

5) Should I make the client acknowledge that data has been received before the server sends more from the buffer?

6) I do not need to do this sort of things when sending stuff like player coordinates, monster attack data, object information etc, etc. So how can I tell when and when not to do the above?

Oh, I almost forgot: I'm using TCP (and I will NOT switch to UDP!! ;-))).



1.) I think a send buffer is a good way to go. Send() returns how much data it was able to successfully send and it isn't always the same length as the amount of data you gave it. If it's less you'll have to handle the remaining data and make sure it gets sent.

A lot these question are answer in the forum FAQ especially in the resources linked to in question 1 from the FAQ there is also sample code.

There are also several Articles on Windows programming in the Articles & Resources section.

I will say TCP handles acknowledging the successful reception of a packet as well as doing CRCs to check data integrity.


Edit:
Sorry you didn't find my response all that helpful. The only reason I directed you to those resources was because they offer example code, and more importantly they answer most, if not all, of your questions. Besides you'll find a lot of posts here the direct people to other places that answer their questions because some aren't aware of those resources and the it's usually explained somewhat better. Why have a forum? So people can discuss, share information, and resources (like links).

[Edited by - prh99 on January 6, 2007 9:02:46 PM]
Patrick
hplus0603
hplus0603
Quote:
I assume I should just use the return value of send() then, to find out how much data was sent and how much to remove from the buffer until next call. The kernel will take care of the rest....?


For a TCP socket, this is correct.

Note that send() may block before it returns a value to you. It may, in fact, block until it's sent all of the data you hand it -- you don't necessarily know. The specifics in when send() will block are something like:

- If at least one byte can be sent right now, then as much as can be sent, is sent, and send() returns with the amount of data sent from the buffer.
- If nothing can be sent right now, and the socket is in blocking mode, then the soket will block until something can be sent, and at that time, whatever can be sent is sent and the amount is returned.
- If nothing can be sent right now, and the socket is in non-blocking mode, an error is return (EWOULDBLOCK).

This means that, after select() returns a socket as writable, it is safe to call send() on it once, without blocking.

If you want a system call that tries to write as much as possible before returning (i e, only returning on actual error), then try using write() on a blocking (default mode) socket, if you're on Linux variants. Or try the function sendfile(). Windows XP has somewhat similar functions, where you can treat a socket as a Windows file handle.
enum Bool { True, False, FileNotFound };
cybernetic
cybernetic
1) You should put the socket into non-blocking mode so the call to send does not hold up the rest of your program. While your program is doing other stuff, the OS will continue sending data and keep the network connection saturated.

2) You can send it all at once. If send doesn't send all of it, it will return a lesser amount of bytes than the amount you requested to send. However, this should not be a problem usually. For large amounts of data, I would advise you to send in fragments and make sure each piece is sent properly.

3) You can send the next one immediately as well. But if you keep handing off large amounts of data to the OS, then somewhere along the line a portion of it won't be sent. This really depends on the specific amount of stuff being sent, the frequency that you have data to send at, etc.

4) Yes.

5) This is a good idea. Although TCP has built in flow control, it is always a good idea to implement some checks in the application to be safe, especially for significant amounts of data.

6) Well I don't think you have to change anything for the other items you list. Off-hand, I would say you should just differentiate what you do based on the amount of data you have to send.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.