本实验为了减少代码量,使用了封装比较完善的http库,本文主要讲述http文件上传的主要要求。
一、分析http关键头部信息
为了分析http header,我们通过chrome得到上传文件时的http信息:
通过上面的截图我们可以发现,关键头部信息为Content-type和Content-length。一般我们写html上传时,都会在form标签加一个multipart-data属性表示该表单有文件上传输入域,so我们在使用c实现http上传的时候,就需要在头部Content-type项加入multipart-data值,有人会问,诶,那后面的boundary是什么?
boundary表示的是每个表单输入域的分界!例:----ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
好了,Content-type有了,接下来我们需要的就是Content-length项的信息了。Content-length表示的是请求内容的长度(byte),那这个长度到底是多大?请看下图:
从图中我们不难看出,Content-length=上传文件大小+输入域头部信息+输入域尾部(byte)。
贴上计算长度的代码一份作为参考:
int get_data_length(int filesize, char* boundary, char* name, char* filename)
{
int nSize = 0;
nSize += strlen("--%s\r\n") + strlen(boundary) - 2;
nSize += strlen("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n") + strlen(name) + strlen(filename) - 4;
nSize += filesize;
nSize += strlen("\r\n--%s--") + strlen(boundary) - 2;
return nSize;
}
二、发送请求和文件
其实在前面的内容基本已经把整篇文章需要讲的讲清楚了,但是我觉得还是贴上具体实现的代码吧!
计算长度:
int get_data_length(int filesize, char* boundary, char* name, char* filename)
{
int nSize = 0;
nSize += strlen("--%s\r\n") + strlen(boundary) - 2;
nSize += strlen("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n") + strlen(name) + strlen(filename) - 4;
nSize += filesize;
nSize += strlen("\r\n--%s--") + strlen(boundary) - 2;
return nSize;
}
经过计算得出这次上传内容的长度,添加到请求头,那么请求头的基本需要的关键信息也已经完成了,之后我们发送该请求。
HTTPAddRequestHeaders( "Content-Type","multipart/form-data; boundary=----ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC");//添加Content-Type
HTTPAddRequestHeaders("Content-Length",get_data_length(filesize, boundary, name, filename));//添加Content-Length
HTTPSendRequest(uri);//发送请求
当我们发送请求成功,就证明客户端已经与服务器建立了tcp连接了,接下来我们继续发送http内容给服务器就行了。
构建上传内容:
char *Buffer=malloc(512);
nSize = 0;
nSize += sprintf(Buffer+nSize, "--%s\r\n", boundary);
nSize += sprintf(Buffer+nSize, "Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n", "pic", "test.mp3");
HTTPWriteData(Buffer, nSize);
do{
menset(Buffer,0,strlen(Buffer));
nSize = ReadFile(File,Buffer,512);//读取文件
HTTPWriteData(Buffer,nSize);//发送文件内容
}while(nSize>0)
menset(Buffer,0,strlen(Buffer));
nSize = sprintf(Buffer, "\r\n--%s--", boundary);
HTTPWriteData(Buffer, nSize);
好了,一个文件的http上传就是这么简单,你现在想试试?