用c socket 方式下载网页

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MaxRecvLen  500

//定义网站结构
struct DOMAIN
{
 char url[255];      //http://www.xh88.com:80/index.php 完整网址
 char host[20];      //www.xh88.com  主机地址
 int  port;       //sock 联接的端口号
};
typedef struct DOMAIN domain;

int main(int argc,char *argv[])
{

//******************* 有关 sock 的变量 *************************

 int sock_id;       //sock 联接句柄

 struct hostent *hostbyname;    //主机的信息 结构
 struct sockaddr_in remote_addr;   //包含远端主机IP地址和端口号的结构


//******************* 有关 无阻塞 select 所用到 的变量 *************************

 struct timeval timeout;     //用于无阻塞 select 调用 的时间变量
 fd_set sockid_readable;     //sock 类似联接句柄 传递给 select 有效的连接

 domain web_domain;      //定义一个 web domain 的结构

 char send_str[255];      //保存要发送的字符串
 char *tempStr,*recBuf;     //临时字串,接收到的字串指针

 int recv_numb;       //保存远端返回的字串大小
 FILE *fp;        //文件指针,用于保存从远端得到的数据
 char *tmpfile;       //临时文件名

 timeout.tv_sec = 1;      //设置几秒钟超时
 timeout.tv_usec = 500000;    //设置几微秒超时
 web_domain.port=80;      //默认端口 为 80

 tmpfile="abc.txt";
//******************* 处理命令行的参数 *************************

 if(argc<2)      //参数不足
 { printf("%s","/n/nExp: ./client http://192.168.1.254:80 /n/n");
  exit(1);
 }
 if(!(tempStr=strstr(argv[1],"http://")))   //必须以 http://开头
 { printf("parameter error!/n");
  exit(0);
 }
 strcpy(web_domain.url,tempStr);      //http://www.xh88.com:80/index.php
 strcpy(web_domain.host,web_domain.url+7);   //www.xh88.com
 //处理 host
 if((tempStr=strstr(web_domain.host,"/")))
 { *tempStr='/0';         //web_domain.host 里去除:后的东西
 }
 if((tempStr=strstr(web_domain.host,":")))
 { *tempStr='/0';         //Host 里去除:后的东西
  web_domain.port=atoi(tempStr+1);    //改写端口
 }
//!
printf("%s/n%d/n%s/n",web_domain.host,web_domain.port,web_domain.url);

 hostbyname = gethostbyname(web_domain.host);  //将基本名字和地址转换
 if((sock_id=socket(PF_INET,SOCK_STREAM,0))==-1)
 { perror("socket");
  exit(1);
 }

//初始化远端要传递的socket
 remote_addr.sin_family=AF_INET;      //地址族
 remote_addr.sin_port=htons(web_domain.port);  //端口号
 remote_addr.sin_addr=*((struct in_addr *)hostbyname->h_addr);  //IP地址
 bzero(&(remote_addr.sin_zero),8);     //填充0 以保持与struct sockaddr同样大小

//和服务器建立连接
 if(connect(sock_id,(struct sockaddr *)&remote_addr,sizeof(remote_addr))==-1)
 { perror("connect");
  exit(1);
 }
printf("/n/nconnected %s:%d ok!/n/n",web_domain.url,web_domain.port);

//创建要发送给远端的字串
 sprintf(send_str,"GET %s HTTP/1.1/nAccept: */*/nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)/nHost: %s/n/n",web_domain.url,web_domain.host);
 printf("%s/n/n",send_str);
//开始向服务器发送数据
 if(send(sock_id,send_str,strlen(send_str),0)==-1)
 { perror("send");
  exit(1);
 }
 recBuf=malloc(MaxRecvLen);  //为储存远端返回的字串的变量申请空间
 //fp=fopen(tmpfile,"w");
 while(1)
 {

//设置无堵塞模式
  FD_ZERO(&sockid_readable);
  FD_SET(sock_id,&sockid_readable);
  select(sock_id+1, &sockid_readable, NULL, NULL, &timeout);
  if (!FD_ISSET(sock_id, &sockid_readable))
  { printf("Timed out./n");
   break;
  }
  recv_numb = recv(sock_id,recBuf,MaxRecvLen,0); //得到远端返回的字串
  recBuf[recv_numb]='/0';

  //fputs(fp,);
  // fp=fopen(tmpfile,"w");
  printf("/n/t********* %d *******",recv_numb);
  printf("%s",recBuf);
  if(recv_numb<1)  //返回的长度不够退出循环
   break;
 }

 printf("/n/nrecv  ok!/n/n");
 close(sock_id);
 return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值