c语言URL通过Http下载mp3 格式

通过http协议下载MP3的关键就是 整块打包,一块一块向文件里面存储。读取的时候用二进制

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

szMp3FileName:将要存储文件的名字
szRequest: 请求内容
szHeadEx: http头附加信息(替换其默认的设置)
iReqType: 请求类型(1--Get;2--Post)
iTimeout: 超时时间(秒)
返回: 页面返回数据
**/

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;
}


块的大小结合实际情况,却大越好,太小的时候,噪音的频率会很高,影响质量,具体消除噪音,以后再改进。

posted @ 2013-08-26 19:04  煮人为乐  阅读(3461)  评论(0编辑  收藏  举报