本實驗爲了減少代碼量,使用了封裝比較完善的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上傳就是這麼簡單,你現在想試試?