在visual studio上调试通过的,这个只是一个示例,还有很多不完善的细节(鲁棒性)需要考虑。
主要流程:
1)创建一个TCP连接
2)发送一个HTTP GET命令
3)读取一段数据,解析出Content-Length字段,找到MP3文件的长度
4)循环读取数据,直到读取到的数据量大于等于MP3文件的长度
#include "stdafx.h"
#include <Winsock2.h>
#include <iostream>
#include <cstdio>
#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
const char CTL_STR[] = "Content-Length";
// 加载socket动态链接库(dll)
WORD wVersionRequested;
WSADATA wsaData; // 这结构是用于接收Wjndows Socket的结构信息的
int err;
FILE *hFile = fopen("out.mp3","wb");
wVersionRequested = MAKEWORD( 1, 1 ); // 请求1.1版本的WinSock库
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return -1; // 返回值为零的时候是表示成功申请WSAStartup
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {
// 检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的1.1版本
// 否则的话,调用WSACleanup()清除信息,结束函数
WSACleanup( );
return -1;
}
// 创建socket操作,建立流式套接字,返回套接字号sockClient
// SOCKET socket(int af, int type, int protocol);
// 第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET)
// 第二个,选择套接字的类型(流式套接字),第三个,特定地址家族相关协议(0为自动)
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
// 将套接字sockClient与远程主机相连
// int connect( SOCKET s, const struct sockaddr* name, int namelen);
// 第一个参数:需要进行连接操作的套接字
// 第二个参数:设定所需要连接的地址信息
// 第三个参数:地址的长度
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("61.155.41.53"); ;
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(80);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
char cmd_str[] = "GET /speeches/obama/Obama%202017-01-13%20Weekly%20Address%20-%20The%20Honor%20of%20Serving%20You%20as%20President.mp3 HTTP/1.1\r\nHOST:www.listeningexpress.com\r\n\r\n";
//通过 TCP 连接,发送 HTTP GET命令
send(sockClient, cmd_str, strlen(cmd_str), 0);
char recvBuf[3001];
int iResult = 0 ;
int i;
int j;
iResult = recv(sockClient, recvBuf, 3000, 0);
char len_str[100];
//to find the "Content-Length"
for(i=0;i<iResult;i++)
{
for( j =0; j<strlen(CTL_STR); j++)
if(recvBuf[i+j] != CTL_STR[j])
break;
if(j == strlen(CTL_STR) )
{
i += j;
break;
}
}
//to get the "Content-Length"
j=0;
for(;i<iResult;i++)
{
if( recvBuf[i] >= '0' && recvBuf[i] <= '9')
{
len_str[j] = recvBuf[i];
len_str[j+1] = 0;
j++;
}
if( (recvBuf[i] == 0x0d) && (recvBuf[i+1] == 0x0a))
break;
}
int length_ctr = atoi(len_str);
//to find the END of Header
for(i=0;i<iResult;i++)
{
if( (recvBuf[i] == 0x0d) && (recvBuf[i+1] == 0x0a) && (recvBuf[i+2] == 0x0d) && (recvBuf[i+3] == 0x0a) )
break;
}
int current_len = iResult - i - 4 ;
fwrite(&recvBuf[i+4], 1, current_len, hFile);
i=1;
do{
memset(recvBuf,0,3001);
iResult = recv(sockClient, recvBuf, 3000, 0);
if(iResult > 0)
{
fwrite(recvBuf, 1, iResult, hFile);
current_len+= iResult;
}
else
printf("no data \n");
if( current_len >= length_ctr )
break;
i++;
}while(iResult > 0);
printf("End linking...\n");
closesocket(sockClient);
WSACleanup(); // 终止对套接字库的使用
fclose(hFile);
printf("\n");
system("pause");
return 0;
}