当前位置: 技术问答>linux和unix
求socket源码:一个最简单的下载工具
来源: 互联网 发布时间:2015-11-10
本文导语: 输入URL(如http://www.am621.com/media/gt/com/真的想你.rm)、保存路径和要保存的文件名,把文件下载下来 | prozilla, kget...很多都有源码的,自己找找 | 用socket实现 get一个文件的思...
输入URL(如http://www.am621.com/media/gt/com/真的想你.rm)、保存路径和要保存的文件名,把文件下载下来
|
prozilla, kget...很多都有源码的,自己找找
|
用socket实现 get一个文件的思路如下:
1.) 用gethostbyname取得站点的IP地址。
2.) 创建一个socket连接该站点的80端口。
3.) 发送HTTP 的GET请求。
4.) 读出server的response,去掉HTTP报头。
5.) 将剩余内容写入文件。
在windows用bsd socket实现的简单代码如下: (在linux上类似)
//windows有个函数URLDownloadToFile可直接下面的功能实现,linux不知道有没有。
//URLDownloadToFile(NULL,"http://www.baidu.com/img/logo.gif","c:\2.jpg",0,NULL);
/* testhttp.c */
#include
#include
#pragma comment(lib, "Ws2_32.lib")
int Send(SOCKET sd, char *fmt, ...);
int ReadEn(int sock,struct timeval tv,int tryloop);
char *ParseHttpHead(char *buf);
int main(int argc, char **argv)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
SOCKET sd;
struct sockaddr_in servaddr;
FILE *fp;
char buf[4096];
struct hostent *hostaddr;
char **h_addr_list;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
printf("sock initialization errorn");
return -1;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
printf("Can not find a correct version socket versionn");
WSACleanup( );
return -1;
}
//以上是windows socket的初始化
sd = socket (AF_INET, SOCK_STREAM, 0);
if ( sd == INVALID_SOCKET )
{
printf("socket() create error n errno = %d", WSAGetLastError());
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
//找到IP地址。
hostaddr = gethostbyname("www.baidu.com");
char **h_addr_list = hostaddr->h_addr_list;
if(*h_addr_list) {
servaddr.sin_addr.S_un.S_addr = ((struct in_addr*)h_addr_list[0])->S_un.S_addr;
}
else {
printf("can not resolve host addressn");
return -1;
}
if ( SOCKET_ERROR == connect(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
{
printf("connect error !n");
return -1;
}
//发送HTTP GET请求
Send(sd, "GET http://www.baidu.com/img/logo.gif Http/1.0rn Accept:
www/source; text/html; image/gif; image/jpeg; */*rnrn");
memset(buf, 0, sizeof(buf));
fp = fopen("tmp.gif", "wb");
if (NULL == fp)
{
printf("fopen file errorn");
WSACleanup( );
return -1;
}
while(1)
{
int readlen = 0;
struct timeval tv;
char *contentptr;
int writelen;
tv.tv_sec = 10;
tv.tv_usec = 0;
//用select观察socket是否可读
readlen = ReadEn(sd, tv ,20);
if (readlen
1.) 用gethostbyname取得站点的IP地址。
2.) 创建一个socket连接该站点的80端口。
3.) 发送HTTP 的GET请求。
4.) 读出server的response,去掉HTTP报头。
5.) 将剩余内容写入文件。
在windows用bsd socket实现的简单代码如下: (在linux上类似)
//windows有个函数URLDownloadToFile可直接下面的功能实现,linux不知道有没有。
//URLDownloadToFile(NULL,"http://www.baidu.com/img/logo.gif","c:\2.jpg",0,NULL);
/* testhttp.c */
#include
#include
#pragma comment(lib, "Ws2_32.lib")
int Send(SOCKET sd, char *fmt, ...);
int ReadEn(int sock,struct timeval tv,int tryloop);
char *ParseHttpHead(char *buf);
int main(int argc, char **argv)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
SOCKET sd;
struct sockaddr_in servaddr;
FILE *fp;
char buf[4096];
struct hostent *hostaddr;
char **h_addr_list;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
printf("sock initialization errorn");
return -1;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
printf("Can not find a correct version socket versionn");
WSACleanup( );
return -1;
}
//以上是windows socket的初始化
sd = socket (AF_INET, SOCK_STREAM, 0);
if ( sd == INVALID_SOCKET )
{
printf("socket() create error n errno = %d", WSAGetLastError());
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
//找到IP地址。
hostaddr = gethostbyname("www.baidu.com");
char **h_addr_list = hostaddr->h_addr_list;
if(*h_addr_list) {
servaddr.sin_addr.S_un.S_addr = ((struct in_addr*)h_addr_list[0])->S_un.S_addr;
}
else {
printf("can not resolve host addressn");
return -1;
}
if ( SOCKET_ERROR == connect(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)))
{
printf("connect error !n");
return -1;
}
//发送HTTP GET请求
Send(sd, "GET http://www.baidu.com/img/logo.gif Http/1.0rn Accept:
www/source; text/html; image/gif; image/jpeg; */*rnrn");
memset(buf, 0, sizeof(buf));
fp = fopen("tmp.gif", "wb");
if (NULL == fp)
{
printf("fopen file errorn");
WSACleanup( );
return -1;
}
while(1)
{
int readlen = 0;
struct timeval tv;
char *contentptr;
int writelen;
tv.tv_sec = 10;
tv.tv_usec = 0;
//用select观察socket是否可读
readlen = ReadEn(sd, tv ,20);
if (readlen