本實(shí)驗(yàn)為了減少代碼量,使用了封裝比較完善的http庫,本文主要講述http文件上傳的主要要求。
一、分析http關(guān)鍵頭部信息
為了分析http header,我們通過chrome得到上傳文件時(shí)的http信息:
通過上面的截圖我們可以發(fā)現(xiàn),關(guān)鍵頭部信息為Content-type和Content-length。一般我們寫html上傳時(shí),都會(huì)在form標(biāo)簽加一個(gè)multipart-data屬性表示該表單有文件上傳輸入域,so我們?cè)谑褂胏實(shí)現(xiàn)http上傳的時(shí)候,就需要在頭部Content-type項(xiàng)加入multipart-data值,有人會(huì)問,誒,那后面的boundary是什么?
boundary表示的是每個(gè)表單輸入域的分界!例:----ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
好了,Content-type有了,接下來我們需要的就是Content-length項(xiàng)的信息了。Content-length表示的是請(qǐng)求內(nèi)容的長(zhǎng)度(byte),那這個(gè)長(zhǎng)度到底是多大?請(qǐng)看下圖:
從圖中我們不難看出,Content-length=上傳文件大小+輸入域頭部信息+輸入域尾部(byte)。
貼上計(jì)算長(zhǎng)度的代碼一份作為參考:
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;
}
二、發(fā)送請(qǐng)求和文件
其實(shí)在前面的內(nèi)容基本已經(jīng)把整篇文章需要講的講清楚了,但是我覺得還是貼上具體實(shí)現(xiàn)的代碼吧!
計(jì)算長(zhǎng)度:
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;
}
經(jīng)過計(jì)算得出這次上傳內(nèi)容的長(zhǎng)度,添加到請(qǐng)求頭,那么請(qǐng)求頭的基本需要的關(guān)鍵信息也已經(jīng)完成了,之后我們發(fā)送該請(qǐng)求。
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);//發(fā)送請(qǐng)求
當(dāng)我們發(fā)送請(qǐng)求成功,就證明客戶端已經(jīng)與服務(wù)器建立了tcp連接了,接下來我們繼續(xù)發(fā)送http內(nèi)容給服務(wù)器就行了。
構(gòu)建上傳內(nèi)容:
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);//發(fā)送文件內(nèi)容
}while(nSize>0)
menset(Buffer,0,strlen(Buffer));
nSize = sprintf(Buffer, "\r\n--%s--", boundary);
HTTPWriteData(Buffer, nSize);
好了,一個(gè)文件的http上傳就是這么簡(jiǎn)單,你現(xiàn)在想試試?