# C++ Win32 Winsock sending a file

This topic is 2185 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

nBuffer is from recv. I open it with the mode binary.

client:
if(std::string(nBuffer)=="FILE_DONE_DOWN") { std::cout<<"Finnished Downloading File: "<<this->Files_To_Update[0]<<'\n'; this->Files_To_Update.erase(this->Files_To_Update.begin()); if(this->Files_To_Update.size()>0) { std::cout<<"Downloading File: "<<this->Files_To_Update[0]<<'\n'; this->Send_Client(this->Files_To_Update[0]); this->WriteToFile.open(this->Files_To_Update[0],this->WriteToFile.binary); } else { std::cout<<"Downloading Executable...\n"; this->Doing="DOWNLOAD_EXE"; this->Send_Client("EXE"); } } else { nBuffer[Size]='\0'; this->WriteToFile.write(nBuffer,Size); this->Send_Client("OK"); std::cout<<nBuffer<<'\n'; }

host:
if(SendFile.is_open()) { char SendBuf[Buff_Size]; //SendFile.seekg(std::ios::beg+DoingAt*Buff_Size); SendFile.read(SendBuf,Buff_Size); APP.Send_Server(SendBuf,p); DoingAt++; if(SendFile.eof()) { SendFile.close(); } std::cout<<SendBuf<<'\n'; } else { APP.Send_Server("FILE_DONE_DOWN",p); DoingAt=0; SendFile.close(); Doing="SEND_FILES"; }

i dont know if this is right, nor if this is the right approach. i was sort of following this tutorial:

but instead of using a CFile i just used a fstream.

Oh, and by files i mean .png,.wav,.ogg, etc.

##### Share on other sites
Does it work? If so, it's probably OK, assuming you give the user proper progress indication, protect against disruptive downloaders on your server, etc.

##### Share on other sites
I really dont know if it works or not. it will start downloading (gibberish, of course) then pause... i know both have to be actively talking to eachother otherwise they both stop, waiting for one to send something when they never will... so as long as i read and write in binary, the files should be ok? i dont know, because you have to have a null terminated string for things... :-\

i really just need to know if this is the right way to read and write any file, and be able to send it.

##### Share on other sites
Sending a binary file but trying to receive it as a null terminated string will not work. Nor will trying to read a binary file and then send it as a null terminated string. The reason is that the binary data may contain zeros, which would screw everything up. You need to first send the number of bytes of the file (either as a string or as binary data), and then when the client receives this they know exactly how many bytes they need to download and don't have to rely on things being null terminated. When sending data, your Send_Server will have to know how many bytes the chunk is that it's sending. I don't know what p is, but it looks like Send_Server is expecting a null terminated C-style string, and binary data does not fit this description.

##### Share on other sites
Ah... how would i read/send/write this binary data? or would it be better to read the files as a actual string?

EDIT:

CFile is a file class that allows binary reading and writing, which is what was used in the tutorial. i have 1 more question though: if you read any file from binary, send it, then write it back in binary, will any file work 100%?

##### Share on other sites
Sending and receiving blocks of bytes is very similar to using void pointers and memcpy(). As long as you can copy data around with memcpy() and void pointers, you can probably also send and receive it on sockets. Or, for that matter, write data to a file and then read it back.
There are some differences:
- if there's a point inside the block of data, that pointer will mean nothing on the other end
- send() may not send everything you ask it to; recv() may receive less than you asked for
- you need to know how much data is to be received, so you know when the next message starts

##### Share on other sites
Well i just learned that CFile is not included with microsoft visual c++ 2010 express, so that wont work. If you know about window sockets (which you probly do), you have to store the recv in a char-array. so how would i store the recv as binary? and the same with send(), how would i send the binary information?

##### Share on other sites
You still store it in a char array. And you still send the data from a char array. It's just not a string. There's a difference between a string and a char array. A C-style string is a special type of char array, but a char array is not necessarily a string (it's kinda like how a square is rectangle, but a rectangle isn't necessarily a square). You just can't treat it as a normal C-style string when you send or receive it though. send() and recv() have absolutely no clue what a string is. All they see is binary data. So even when you send/receive a string with them, all the see it as is a plain old binary char array.

##### Share on other sites
Yeah, i sort of figured that out now. I knew that a string is always null terminated, etc etc... i just now tested with a .txt file, and works well. but when its other files, like .wav s and .png s, it gets buggy. also, i tried getting the file size by doing:
SendFile.open(nMess,SendFile.binary); std::stringstream LengthBuf; SendFile.seekg(std::ios::end); LengthBuf<<SendFile.tellg(); std::cout<<"Sending File Length: "<<LengthBuf.str()<<'\n'; SendFile.seekg(std::ios::beg);

and always calls it 2... but otherwise... regular text files work... how would i do this with others?

EDIT:

I found out how to get the size... now i just have to work on the other types of files...

##### Share on other sites
Is there any reason you are doing this in-band? If you were to host the files on a web server, you could use a simple HTTP library to manage most of this for you. In addition, you might want to separate the updater from the game. Doing this will keep each component simpler.

##### Share on other sites
XD i dont have any money to do anything like that. and if i did, i dont think it would be worth it since no body really plays my game. i mean, if you ever heard of N8, they started kinda like me... but once they started getting players and more money they could spend it on stuff like that. but for now, im trying to do it as easy and free as possible.

##### Share on other sites
Could anyone post some example code for both the client and host that uses fstream to read,send,receive,and write binary files?

##### Share on other sites
If it works for text files, and not for arbitrary data, then you must be relying on some property in text - an assumption that "binary" data violates. The most obvious example would be assuming that the 0 byte cannot occur in the data. That or accidentally treating the data as if it were a string, for example using the strlen() function.

##### Share on other sites
Nevermind, works perfectly!
Im proud of myself.