2015-10-26 40 views
1

我想通过使用send()和recv()在http上传输一个结构(有数据和ID等)。通过TCP,以下两行完美地工作。使用套接字发送一个结构通过http

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

但是,当通过HTTP,在StructToRecv只得到两个字节凌乱这样的代码:EE

////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); 
+0

你的'sprintf_s()'调用之一缺少一个右括号;代码显示无法编译。 'sprintf_s()'的C11附件K定义是:'int sprintf_s(char * restrict s,rsize_t n,const char * restrict format,...);'即使微软可能不完全匹配('int sprintf_s(char * buffer,size_t sizeOfBuffer,const char * format [,argument] ...);',作为第二个参数没有传入一个大小会导致可怕的作弊行为,也无法可靠地传递目标字符串('header ')作为要处理的参数之一 - 它会产生未定义的行为**重新考虑!** –

+1

请注意,不推荐使用这种方式发送结构(通过HTTP,TCP或任何其他协议),因为内存结构的布局不能保证在网络连接的两侧都是相同的,如果它不同,接收方会误解传入的数据。发送数据的正确方式是文本或成员数据项通过成员数据项,这样就可以很好地定义线上数据格式(许多程序员选择使用serializ ation library来处理这个任务) –

+0

@JeremyFriesner我不应该使用第三个库。我该如何解决这个问题? –

回答

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

您正在使用sprintf(...%s..)。这意味着您给出的数据被视为以\0结尾的字符串,即只包含直到第一个\0的数据。

+0

我应该使用什么?有代码的任何建议吗? –

+0

我应该首先将StructToSend转换为char字符串吗? –

+0

@MinKim:你不能使用像sprintf,strcpy,strlen等任何字符串函数和包含'\ 0'的二进制数据。字符串函数仅适用于(非二进制)字符串,其他所有内容都使用memcpy和类似的函数。 –