• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Zomgbie

recv() stops when there's exactly 508 bytes left.

17 posts in this topic

Hello you!

As the topic states, my recv() call keeps stopping when there is 508 bytes left to read. I'm trying to send a file, and it's all going good untill we hit the magical 508 bar.

Sending
[code]

void
sendFile(char *fileName)
{
struct fileInfo info;
FILE *file;
long fileSize;
char *buffer, temp[512];
int left, sent, total;

/* Open the file */
file = fopen(fileName, "rb");
if (file == NULL)
logThis("sendFile", "Out of memory while opening file.");

/* Obtain file zie */
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
rewind(file);

/* Allocate memory for the buffer */
buffer = (char *)malloc(sizeof(char) * fileSize);
if (buffer == NULL) {
logThis("sendFile", "Out of memory.");
exit(99);
}

/* Copy file contents over to our buffer */
fread(buffer, 1, fileSize, file);
logThis("sendFile", "Buffer contains: %s", buffer);

/* Send the file name first, and then our size */
info.size = fileSize;
snprintf(info.name, 32, "%s", fileName);
logThis("sendFile", "Name: %s, size: %d", info.name, info.size);
sendCommand(NET_FILEINFO, (char *)&info);

/* Start sending file */
total = 0;
left = fileSize;
logThis("sendFile", "Ready to send: %d bytes", left);
while (total < fileSize) {
sent = send(serverSocket, buffer + total, left, 0);


if (sent == 0) {
logThis("handle", "Connection closed during transfer");
break;
} else if (sent < 0) {
logThis("handle", "Error during tansfer!");
break;
} else {
total += sent;
left -= sent;
logThis("sendFile", "Sent: %d bytes. %d bytes left", sent, left);
}
}
logThis("sendFile", "Done sending. Sent: %d vs %d", total, fileSize);
}
[/code]

And where i get the file
[code]

void
*handle(void *argument)
{
struct fileClient *client;
struct fileInfo *info;
char buffer[512], *fileBuffer;
FILE *file;
int total, read, ret;

/* Get the client */
client = (struct fileClient *)argument;

/* Ready for files, send OK message */
sendCommand(client->clientSocket, NET_OK, " ");

/* Expect file name and then size */
recvCommand(client->clientSocket, NET_FILEINFO, buffer);
info = (struct fileInfo *)buffer;
logThis("handle", "File name: %s file size: %d", info->name, info->size);

/* Allocate memory for the file */
fileBuffer = (char *)malloc(info->size);

/* Keep recieving data and copying it into the file buffer untill done */
total = 0;
read = info->size;
while (read > 0) {
ret = recv(client->clientSocket, (fileBuffer + total), read, 0);

if (ret == 0) {
logThis("handle", "Connection closed during transfer");
break;
} else if (ret < 0) {
logThis("handle", "Error during tansfer!");
break;
} else {
total += ret;
read -= ret;
logThis("handle", "Read: %d bytes. %d bytes left", ret, read);
}
}

/* Create the file on disk and save it */
file = fopen(info->name, "wb");
fwrite(fileBuffer, 1, info->size, file);
fclose(file);
pthread_exit(NULL);
}[/code]

I should note that sometimes, the file manages to be downloaded completly.
0

Share this post


Link to post
Share on other sites
Your while(total < left) loop will be wrong when you both increase total and decrease left, as they will meet on the middle. You probably want while(total < filesize).
0

Share this post


Link to post
Share on other sites
You're correct. Not sure what i missed in my calculations, but indeed, it will skip when they meet on the middle.

But i still have the exact same problem. My send() function reports that all data have been sent, but when the recv() functions hits 508 bytes, it just stops :(
0

Share this post


Link to post
Share on other sites
Change your client loop like this, and see if you get some new output.
[code]
ret = recv(client->clientSocket, (fileBuffer + total), read, 0);
if(ret == 0)
// connection closed
else if(ret < 0)
// error
else {
total += ret;
read -= ret;
}
[/code]

Also, print out (or check with the debugger) the first 50 bytes or something of the file, to make sure they are equal on the server and client-side, so you don't miss any data at the start.
0

Share this post


Link to post
Share on other sites
Nothing new sadly.

When there is 508 bytes left to read, recv just stops receiving. It will block the flow of the program (I'm using blocking sockets) untill the poor server shuts down, and therefore disconnects the client. There are no errors, and ret == 0 does not happend untill i actually shutdown the server. Feeling like i've gotten something very wrong, somewhere!

The output
[code]
...

[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 96348 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 79964 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 63580 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 47196 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 30812 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 16384 bytes. 14428 bytes left
[backupTool][2011-02-24][14:59:29][handle]: Read: 13920 bytes. 508 bytes left
... Nothing happens here, untill i disconnect the server. Then it says:

[backupTool][2011-02-24][14:59:40][handle]: Connection closed during transfer
[/code]
0

Share this post


Link to post
Share on other sites
Did you compare the data you actually receive with the data you send on the server?
Try printing out the last 10 bytes sent from the server and the last 10 bytes received on the client, to make sure your data isn't just offset 508 bytes, and the last byte you received is actually supposed to be at the end of the file. For example open your file in a hex editor and type 'test123' at the end or something, and make sure it is actually sent and not received.
0

Share this post


Link to post
Share on other sites
Tried that out now. All bytes are identical untill we hit the 508 mark, where i cannot compare anymore :(
0

Share this post


Link to post
Share on other sites
Right now it does. It waits for 1 minut after sending, and then closes the socket. When i'm done with this, i'm not planning on closing the socket after the transfer. There is more data to be sent afterwards :)
0

Share this post


Link to post
Share on other sites
It should work. Try flushing the socket immediately after finishing anyway. You might also try disabling Nagle's algorithm, but I don't think that should be causing a problem as your clinet should be acknowledging every read().

Can you post a minimal client that demonstrates this behaviour? What about trying to readthe data byte by byte into the buffer? It does seem that your code has an issue when the "data left" drops below the size 16384.
0

Share this post


Link to post
Share on other sites
Make sure you implement Erik's logic from post #4 for the send code as well on the server. Specifically, you need to make sure -1 is not returned on the send logic because you might be filling up the client's send buffer too fast on the server.

To help test that as well, you can increase the size of the send/recv buffers on sockets as well as disable nagle's algorithm. Check out the [url="http://msdn.microsoft.com/en-us/library/ms740476%28v=vs.85%29.aspx"]setsockopt[/url] function as well as the SO_RCVBUF, SO_SNDBUF, SO_LINGER, and TCP_NODELAY settings. You might need to Google for a few specific examples to read up on which settings might be best to try for your specific application.

Lastly, make sure you don't have any bugs in the actual debugging output statements you are using. I.e., I've done silly things in the past where I outputted a size before I modified it correctly so it always looked like there was data left, but there really wasn't. I'm not sure what your specific code looks like right now after modifications, but the last debug output seemed not to print enough variable information.
0

Share this post


Link to post
Share on other sites
[quote name='Zomgbie' timestamp='1298551049' post='4778405']
As the topic states, my recv() call keeps stopping when there is 508 bytes left to read. I'm trying to send a file, and it's all going good untill we hit the magical 508 bar.
[/quote]


People already talked about the while() loop on the sending side.
How do sender and receiver communicate the file size in the first place? If you print it before the while() loop on each side, do they agree?
-1

Share this post


Link to post
Share on other sites
The loop already checks for errors, and disconnects. But it never gets there, because recv() seems to wait for data thats not there.

Drew, i'll take a closer look at what you wrote when i get home.

Hplus, the client will send the file size and name as a structred packet. The server picks up on this and expect the next input on the wire to be the actual file. If i'm printing the file size on both server and client, theh are the same.

I should note that smaller files that only takes up a few loops, get through without problem.'i'll post the updated functions when i get home.

Thanks for all the awesome help so far :)
0

Share this post


Link to post
Share on other sites
You should get into the habit of posting your [b]actual[/b] code, as the problem might very well be clearly visible there, and not pretend code that might not contain the same error. Include the parts that deal with sending the file size etc. before the file loop also.
0

Share this post


Link to post
Share on other sites
[quote name='Erik Rufelt' timestamp='1298621804' post='4778819']
You should get into the habit of posting your [b]actual[/b] code...
[/quote]

Point taken! I've updated my first post with the two actual functions that takes care of sending/recv.

Edit: The formatting is a bit off, sorry for that.
0

Share this post


Link to post
Share on other sites
We still can't see your socket setup, and I don't see the server's socket being flushed or closed as previously suggested. If you could develop a minimal client (all in one file) that demonstrates the behaviour that would be easiest for us (as we can test it in isolation and see everything).
0

Share this post


Link to post
Share on other sites
How does recvCommand(client->clientSocket, NET_FILEINFO, buffer) work?
Make sure you don't read more than the number of bytes sent by the server's sendCommand(NET_FILEINFO, (char *)&info), or you might get part of the file in 'buffer' in that read. If you investigated the file-contents to be correct even when you don't receive the entire file that shouldn't be possible, but it seems the most likely issue from your code, so I would double-check that.
0

Share this post


Link to post
Share on other sites
[quote name='Zomgbie' timestamp='1298615650' post='4778801']
Hplus, the client will send the file size and name as a structred packet. The server picks up on this and expect the next input on the wire to be the actual file. If i'm printing the file size on both server and client, theh are the same.
[/quote]

Are you sure that you're not accidentally reading more than was put in there for the file size packet?
Note that TCP is a stream protocol, not a packet protocol. You have to packetize and re-buffer yourself.
If you check the contents of the file that is received, are you missing the FIRST 508 bytes, or the LAST 508 bytes?
-1

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  
Followers 0