c語言URL經過Http下載mp3 格式

經過http協議下載MP3的關鍵就是 整塊打包,一塊一塊向文件裏面存儲。讀取的時候用二進制服務器

/***
szWebAddr: 頁面地址(包含host+addr)app

szMp3FileName:將要存儲文件的名字
szRequest: 請求內容
szHeadEx: http頭附加信息(替換其默認的設置)
iReqType: 請求類型(1--Get;2--Post)
iTimeout: 超時時間(秒)
返回: 頁面返回數據
**/socket

int  GetDataFromWebByte(char *szWebAddr,char *szMp3FileName , char *szRequest, char *szHeadEx, int iReqType, int iTimeout)
{
    char szHost[128] = "", szAddr[512] = "";
    char  szWebBuf[4096] = "",   szBuf[4096] = "";
    char *pRetData = NULL;        //返回的數據
    char *szHead = NULL;
    int iPort = 80, iAppSock;
    int iRet = 0, iLen, k, iChars, iDone;
    int iContentLen, iChunked = 0;
    struct sockaddr_in appHostAddr;
    struct hostent *pHostent = NULL;
    int iTransferType = 0, iContent = 0;
    FILE *fp;
    WSADATA wsa={0};

    if(!szWebAddr)
        return 0;
    WSAStartup(MAKEWORD(2,2),&wsa);

    //獲取host和addr和port
    iRet = GetHostandAddr(szWebAddr, szHost, sizeof(szHost), szAddr, sizeof(szAddr), &iPort);
    if(iRet < 1)
        return 0;

    //獲取hostent
    pHostent = gethostbyname(szHost);
    if(!pHostent)
    {
        iRet = WSAGetLastError();
        
        return 0;
    }

    //建立socket
    appHostAddr.sin_family = AF_INET;
    appHostAddr.sin_port = htons((unsigned short)iPort);
    appHostAddr.sin_addr.s_addr = ((struct in_addr *)(pHostent->h_addr))->s_addr;
    iAppSock = socket(AF_INET, SOCK_STREAM, 0);
    if(iAppSock == -1)
    {
        return 0;
    }

    //將建立的Socket鏈接至應用服務器
    if(connect(iAppSock, (void *)&appHostAddr, sizeof(appHostAddr)) == -1)
    {
        return 0;
    }

    //配置httphead
    szHead = GetHttpHead(szHost, szAddr, szRequest, szHeadEx, iReqType);
    if(!szHead)
        return 0;

    //嚮應用服務器發送HTTP請求
    if(send(iAppSock, szHead, strlen(szHead), 0) == -1){        
        return 0;
    }
    free(szHead);
    szHead = NULL;

    //接收應用服務器返回的數據
    memset(szWebBuf, 0, sizeof(szWebBuf));
    memset(szBuf, 0, sizeof(szBuf));
    k = 0;
    iChars = 0;
    iDone = 0;
    //獲取http頭信息
    while(iDone == 0)
    {
        iLen = RecvHttpData(iAppSock, szWebBuf, 1, iTimeout);
        if(iLen < 1)
            iDone = 1;
        switch(*szWebBuf)
        {
        case '\r':
            break;
        case '\n':
            if(iChars == 0)
                iDone = 1;
            iChars = 0;
            break;
        default:
            iChars++;
            break;
        }
        if(k < sizeof(szBuf) - 1)
        {
            szBuf[k] = szWebBuf[0];
            k++;
        }
        else
        {
            pRetData = addRevData(pRetData, szBuf);
            memset(szBuf, 0, sizeof(szBuf));
            k = 0;
            szBuf[k] = szWebBuf[0];
            k++;
        }
    }
    pRetData = addRevData(pRetData, szBuf);

    //獲取http內容長度
    //判斷是否chunked
    if(strstr(pRetData, "chunked"))
        iChunked = 1;    //爲chunk傳輸

    //獲取http內容
    iContent = 1;
    do 
    {
        if (iChunked > 0)
        {
            iContentLen = GetChunkedContentLength(iAppSock);
        }
        else
        {
            iContentLen = GetContentLength(pRetData);
        }
        //獲取http內容
        //清空數據
        if(iContent == 1 && pRetData)
        {
            free(pRetData);
            pRetData = NULL;
            iContent = 2;
        }
        if(iContentLen < 1)
        {
            closesocket(iAppSock);
            //close(iAppSock);
            return 1;
        }
        
        //chunk
        memset(szWebBuf, 0, sizeof(szWebBuf));
        memset(szBuf, 0, sizeof(szBuf));
        k = 0;
        iChars = iContentLen;
        //*iLenByte = iChars;
        iDone = 0;
        fp = fopen(szMp3FileName , "wb+");
        while(iDone == 0)
        {
            iLen = RecvHttpData(iAppSock, szWebBuf, 1, iTimeout);
            if(iLen < 1)
                iDone = 1;
            iChars--;
            if(iChars < 1)
                iDone = 1;
            if(k < sizeof(szBuf) - 1)
            {
                szBuf[k] = szWebBuf[0];
                k++;
            }
            else
            {
            //    puts(szBuf);
                fwrite(szBuf,1,4096,fp);
                memset(szBuf, 0, sizeof(szBuf));
                k = 0;
                szBuf[k] = szWebBuf[0];
                k++;
            }
        }
        fclose(fp);
        
    } 

    while (iChunked);    //chunk格式才繼續找

    closesocket(iAppSock);
    WSACleanup();
    return 1;
}


塊的大小結合實際狀況,卻大越好,過小的時候,噪音的頻率會很高,影響質量,具體消除噪音,之後再改進。spa

相關文章
相關標籤/搜索