1

I want to transfer a struct (has data and ID etc.) over http using send() and recv(). Over TCP the following two lines works perfectly.

Client: send(sock, (char *)&StructToSend, sizeof(StructToSend), 0); Server: recv(sock, (char *)&StructToRecv, sizeof(StructToRecv),0); 

But when over HTTP, the StructToRecv gets only two bytes messy code like this: ÈÈ

 ////Client code: send over http int length = 0; char header[4096]; char tmp_name[80]; memset(tmp_name, 0, sizeof(tmp_name)); strcat_s(tmp_name, "tmp.txt"); length = (sizeof(SendStruct)+strlen(tmp_name)+ 287); sprintf_s(header, "POST /%s/index.html HTTP/1.1\r\n", sub_dir; sprintf_s(header, "%sHost: %s \r\n", header , szIP); sprintf_s(header, "%sUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0\r\n", header); sprintf_s(header, "%sAccept: text/html;q=0.9,*/*;q=0.8\r\n", header); sprintf_s(header, "%sAccept-Language: en-US,en;q=0.5\r\n", header); sprintf_s(header, "%sAccept-Encoding: gzip, deflate\r\n", header); sprintf_s(header, "%sConnection: Keep-Alive\r\n", header); sprintf_s(header, "%sContent-Type: multipart/form-data; boundary=-----------------------------26774670897926\r\n", header); sprintf_s(header, "%sContent-Length: %d\r\n", header, length ); sprintf_s(header, "%s\r\n", header); //blank line sprintf_s(header, "%s-------------------------------26774670897926\r\n", header); sprintf_s(header, "%sContent-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n", header, tmp_name); sprintf_s(header, "%sContent-Type: text/plain\r\n", header); sprintf_s(header, "%s\r\n", header); //blank line sprintf_s(header, "%s%s\r\n", header, (char *)&StructToSend ); sprintf_s(header, "%s-------------------------------26774670897926\r\n", header); sprintf_s(header, "%sContent-Disposition: form-data; name=\"submit\"\r\n", header); sprintf_s(header, "%s\r\n", header); sprintf_s(header, "%sSubmit\r\n\r\n", header); sprintf_s(header, "%s-------------------------------26774670897926--\r\n\r\n\0", header); send(sock, header, sizeof(header), 0); ////Server code : recv over http char http_data[4096] = { '\0' }; ZeroMemory( http_data, sizeof( http_data)); recv(sock, http_data, 4096, 0); 
4
  • One of your sprintf_s() calls is missing a close parenthesis; there's no way the code shown compiles. The C11 Annex K definition of sprintf_s() is: int sprintf_s(char * restrict s, rsize_t n, const char * restrict format, ...); Even though Microsoft probably doesn't quite match that (int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... );, you're cheating horribly by not passing a size as the second argument. You also cannot reliably pass the target string (header) as one of the arguments to be processed — it yields undefined behaviour. Rethink! Commented Oct 26, 2015 at 4:49
  • 1
    Note that sending a struct this way (over HTTP, TCP, or any other protocol) is not recommended, because the in-memory layout of the struct is not guaranteed to be the same on both sides of the network connection, and if it differs, then the receiver will misinterpret the incoming data. The correct way to send data is either as text, or member-data-item by member-data-item so that the over-the-wire data format will be well defined. (Many programmers choose to use a serialization library to handle this task for them) Commented Oct 26, 2015 at 4:53
  • @JeremyFriesner I'm not supposed to use third library. How can I fix that? Commented Oct 26, 2015 at 6:31
  • Data serialization is its own topic, so I can't provide an adequate answer in a comment, but here is a link to get you started: stackoverflow.com/search?q=how+to+serialize+data+%5Bc%5D Commented Oct 26, 2015 at 17:15

1 Answer 1

3
sprintf_s(header, "%s%s\r\n", header, (char *)&StructToSend ); 

You are using sprintf(...%s..). This means the data you give are treated as a char string terminated with \0, i.e. only data up to the first \0 will be included.

Sign up to request clarification or add additional context in comments.

9 Comments

What should I use? Any suggestions with code please?
Should I convert StructToSend to a char string first?
@MinKim: you cannot use any string functions like sprintf, strcpy, strlen etc with binary data containing \0. String functions are for (non-binary) strings only, for everything else use memcpy and similar functions.
You also should not even attempt sending binary struct representation over the wire. A recipe for disaster.
Can you please write code for example? My struct contains int, DWORD, and data (for transferring files content )
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.